diff options
Diffstat (limited to 'drivers/rtc/rtc-omap.c')
-rw-r--r-- | drivers/rtc/rtc-omap.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index bd1ce8e2bc18..73377b0d65da 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -34,7 +34,8 @@ | |||
34 | * Board-specific wiring options include using split power mode with | 34 | * Board-specific wiring options include using split power mode with |
35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), | 35 | * RTC_OFF_NOFF used as the reset signal (so the RTC won't be reset), |
36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from | 36 | * and wiring RTC_WAKE_INT (so the RTC alarm can wake the system from |
37 | * low power modes). See the BOARD-SPECIFIC CUSTOMIZATION comment. | 37 | * low power modes) for OMAP1 boards (OMAP-L138 has this built into |
38 | * the SoC). See the BOARD-SPECIFIC CUSTOMIZATION comment. | ||
38 | */ | 39 | */ |
39 | 40 | ||
40 | #define OMAP_RTC_BASE 0xfffb4800 | 41 | #define OMAP_RTC_BASE 0xfffb4800 |
@@ -87,9 +88,10 @@ | |||
87 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) | 88 | #define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3) |
88 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) | 89 | #define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2) |
89 | 90 | ||
91 | static void __iomem *rtc_base; | ||
90 | 92 | ||
91 | #define rtc_read(addr) omap_readb(OMAP_RTC_BASE + (addr)) | 93 | #define rtc_read(addr) __raw_readb(rtc_base + (addr)) |
92 | #define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) | 94 | #define rtc_write(val, addr) __raw_writeb(val, rtc_base + (addr)) |
93 | 95 | ||
94 | 96 | ||
95 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), | 97 | /* we rely on the rtc framework to handle locking (rtc->ops_lock), |
@@ -330,32 +332,31 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
330 | return -ENOENT; | 332 | return -ENOENT; |
331 | } | 333 | } |
332 | 334 | ||
333 | /* NOTE: using static mapping for RTC registers */ | ||
334 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 335 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
335 | if (res && res->start != OMAP_RTC_BASE) { | 336 | if (!res) { |
336 | pr_debug("%s: RTC registers at %08x, expected %08x\n", | 337 | pr_debug("%s: RTC resource data missing\n", pdev->name); |
337 | pdev->name, (unsigned) res->start, OMAP_RTC_BASE); | ||
338 | return -ENOENT; | 338 | return -ENOENT; |
339 | } | 339 | } |
340 | 340 | ||
341 | if (res) | 341 | mem = request_mem_region(res->start, resource_size(res), pdev->name); |
342 | mem = request_mem_region(res->start, | ||
343 | res->end - res->start + 1, | ||
344 | pdev->name); | ||
345 | else | ||
346 | mem = NULL; | ||
347 | if (!mem) { | 342 | if (!mem) { |
348 | pr_debug("%s: RTC registers at %08x are not free\n", | 343 | pr_debug("%s: RTC registers at %08x are not free\n", |
349 | pdev->name, OMAP_RTC_BASE); | 344 | pdev->name, res->start); |
350 | return -EBUSY; | 345 | return -EBUSY; |
351 | } | 346 | } |
352 | 347 | ||
348 | rtc_base = ioremap(res->start, resource_size(res)); | ||
349 | if (!rtc_base) { | ||
350 | pr_debug("%s: RTC registers can't be mapped\n", pdev->name); | ||
351 | goto fail; | ||
352 | } | ||
353 | |||
353 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 354 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
354 | &omap_rtc_ops, THIS_MODULE); | 355 | &omap_rtc_ops, THIS_MODULE); |
355 | if (IS_ERR(rtc)) { | 356 | if (IS_ERR(rtc)) { |
356 | pr_debug("%s: can't register RTC device, err %ld\n", | 357 | pr_debug("%s: can't register RTC device, err %ld\n", |
357 | pdev->name, PTR_ERR(rtc)); | 358 | pdev->name, PTR_ERR(rtc)); |
358 | goto fail; | 359 | goto fail0; |
359 | } | 360 | } |
360 | platform_set_drvdata(pdev, rtc); | 361 | platform_set_drvdata(pdev, rtc); |
361 | dev_set_drvdata(&rtc->dev, mem); | 362 | dev_set_drvdata(&rtc->dev, mem); |
@@ -380,13 +381,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
380 | dev_name(&rtc->dev), rtc)) { | 381 | dev_name(&rtc->dev), rtc)) { |
381 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", | 382 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", |
382 | pdev->name, omap_rtc_timer); | 383 | pdev->name, omap_rtc_timer); |
383 | goto fail0; | 384 | goto fail1; |
384 | } | 385 | } |
385 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, | 386 | if ((omap_rtc_timer != omap_rtc_alarm) && |
386 | dev_name(&rtc->dev), rtc)) { | 387 | (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, |
388 | dev_name(&rtc->dev), rtc))) { | ||
387 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", | 389 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", |
388 | pdev->name, omap_rtc_alarm); | 390 | pdev->name, omap_rtc_alarm); |
389 | goto fail1; | 391 | goto fail2; |
390 | } | 392 | } |
391 | 393 | ||
392 | /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ | 394 | /* On boards with split power, RTC_ON_NOFF won't reset the RTC */ |
@@ -400,16 +402,17 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
400 | 402 | ||
401 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: | 403 | /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: |
402 | * | 404 | * |
403 | * - Boards wired so that RTC_WAKE_INT does something, and muxed | 405 | * - Device wake-up capability setting should come through chip |
404 | * right (W13_1610_RTC_WAKE_INT is the default after chip reset), | 406 | * init logic. OMAP1 boards should initialize the "wakeup capable" |
405 | * should initialize the device wakeup flag appropriately. | 407 | * flag in the platform device if the board is wired right for |
408 | * being woken up by RTC alarm. For OMAP-L138, this capability | ||
409 | * is built into the SoC by the "Deep Sleep" capability. | ||
406 | * | 410 | * |
407 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, | 411 | * - Boards wired so RTC_ON_nOFF is used as the reset signal, |
408 | * rather than nPWRON_RESET, should forcibly enable split | 412 | * rather than nPWRON_RESET, should forcibly enable split |
409 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT | 413 | * power mode. (Some chip errata report that RTC_CTRL_SPLIT |
410 | * is write-only, and always reads as zero...) | 414 | * is write-only, and always reads as zero...) |
411 | */ | 415 | */ |
412 | device_init_wakeup(&pdev->dev, 0); | ||
413 | 416 | ||
414 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) | 417 | if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT) |
415 | pr_info("%s: split power mode\n", pdev->name); | 418 | pr_info("%s: split power mode\n", pdev->name); |
@@ -419,10 +422,12 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
419 | 422 | ||
420 | return 0; | 423 | return 0; |
421 | 424 | ||
422 | fail1: | 425 | fail2: |
423 | free_irq(omap_rtc_timer, NULL); | 426 | free_irq(omap_rtc_timer, NULL); |
424 | fail0: | 427 | fail1: |
425 | rtc_device_unregister(rtc); | 428 | rtc_device_unregister(rtc); |
429 | fail0: | ||
430 | iounmap(rtc_base); | ||
426 | fail: | 431 | fail: |
427 | release_resource(mem); | 432 | release_resource(mem); |
428 | return -EIO; | 433 | return -EIO; |
@@ -430,7 +435,7 @@ fail: | |||
430 | 435 | ||
431 | static int __exit omap_rtc_remove(struct platform_device *pdev) | 436 | static int __exit omap_rtc_remove(struct platform_device *pdev) |
432 | { | 437 | { |
433 | struct rtc_device *rtc = platform_get_drvdata(pdev);; | 438 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
434 | 439 | ||
435 | device_init_wakeup(&pdev->dev, 0); | 440 | device_init_wakeup(&pdev->dev, 0); |
436 | 441 | ||
@@ -438,7 +443,9 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) | |||
438 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); | 443 | rtc_write(0, OMAP_RTC_INTERRUPTS_REG); |
439 | 444 | ||
440 | free_irq(omap_rtc_timer, rtc); | 445 | free_irq(omap_rtc_timer, rtc); |
441 | free_irq(omap_rtc_alarm, rtc); | 446 | |
447 | if (omap_rtc_timer != omap_rtc_alarm) | ||
448 | free_irq(omap_rtc_alarm, rtc); | ||
442 | 449 | ||
443 | release_resource(dev_get_drvdata(&rtc->dev)); | 450 | release_resource(dev_get_drvdata(&rtc->dev)); |
444 | rtc_device_unregister(rtc); | 451 | rtc_device_unregister(rtc); |