diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-06-30 14:41:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-30 21:56:01 -0400 |
commit | 9980060bad5607ca6db7fb8683de671b522e56a4 (patch) | |
tree | d9b80a9768d96f721625b32a2c9559d57dff48da /drivers/rtc/rtc-bfin.c | |
parent | ee905d0c58a440a5bd10c845e8305f6f7f706be2 (diff) |
bfin: delay IRQ registration until driver is ready
Make sure we do not actually request the RTC IRQ until the device driver
is fully ready to handle and process any interrupt. This way a spurious
interrupt won't crash the system (which may happen if the bootloader was
poking the RTC right before booting Linux).
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc/rtc-bfin.c')
-rw-r--r-- | drivers/rtc/rtc-bfin.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index aafd3e6ebb0d..a118eb0f1e67 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -1,8 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] | 3 | * Supports BF51x/BF52x/BF53[123]/BF53[467]/BF54x |
4 | * | 4 | * |
5 | * Copyright 2004-2008 Analog Devices Inc. | 5 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * | 6 | * |
7 | * Enter bugs at http://blackfin.uclinux.org/ | 7 | * Enter bugs at http://blackfin.uclinux.org/ |
8 | * | 8 | * |
@@ -363,7 +363,7 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
363 | struct bfin_rtc *rtc; | 363 | struct bfin_rtc *rtc; |
364 | struct device *dev = &pdev->dev; | 364 | struct device *dev = &pdev->dev; |
365 | int ret = 0; | 365 | int ret = 0; |
366 | unsigned long timeout; | 366 | unsigned long timeout = jiffies + HZ; |
367 | 367 | ||
368 | dev_dbg_stamp(dev); | 368 | dev_dbg_stamp(dev); |
369 | 369 | ||
@@ -374,32 +374,32 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
374 | platform_set_drvdata(pdev, rtc); | 374 | platform_set_drvdata(pdev, rtc); |
375 | device_init_wakeup(dev, 1); | 375 | device_init_wakeup(dev, 1); |
376 | 376 | ||
377 | /* Register our RTC with the RTC framework */ | ||
378 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, | ||
379 | THIS_MODULE); | ||
380 | if (unlikely(IS_ERR(rtc->rtc_dev))) { | ||
381 | ret = PTR_ERR(rtc->rtc_dev); | ||
382 | goto err; | ||
383 | } | ||
384 | |||
377 | /* Grab the IRQ and init the hardware */ | 385 | /* Grab the IRQ and init the hardware */ |
378 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); | 386 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev); |
379 | if (unlikely(ret)) | 387 | if (unlikely(ret)) |
380 | goto err; | 388 | goto err_reg; |
381 | /* sometimes the bootloader touched things, but the write complete was not | 389 | /* sometimes the bootloader touched things, but the write complete was not |
382 | * enabled, so let's just do a quick timeout here since the IRQ will not fire ... | 390 | * enabled, so let's just do a quick timeout here since the IRQ will not fire ... |
383 | */ | 391 | */ |
384 | timeout = jiffies + HZ; | ||
385 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) | 392 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) |
386 | if (time_after(jiffies, timeout)) | 393 | if (time_after(jiffies, timeout)) |
387 | break; | 394 | break; |
388 | bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); | 395 | bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE); |
389 | bfin_write_RTC_SWCNT(0); | 396 | bfin_write_RTC_SWCNT(0); |
390 | 397 | ||
391 | /* Register our RTC with the RTC framework */ | ||
392 | rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE); | ||
393 | if (unlikely(IS_ERR(rtc->rtc_dev))) { | ||
394 | ret = PTR_ERR(rtc->rtc_dev); | ||
395 | goto err_irq; | ||
396 | } | ||
397 | |||
398 | return 0; | 398 | return 0; |
399 | 399 | ||
400 | err_irq: | 400 | err_reg: |
401 | free_irq(IRQ_RTC, dev); | 401 | rtc_device_unregister(rtc->rtc_dev); |
402 | err: | 402 | err: |
403 | kfree(rtc); | 403 | kfree(rtc); |
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |