diff options
Diffstat (limited to 'drivers/rtc')
| -rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 4 | ||||
| -rw-r--r-- | drivers/rtc/rtc-omap.c | 4 | ||||
| -rw-r--r-- | drivers/rtc/rtc-sh.c | 246 | ||||
| -rw-r--r-- | drivers/rtc/rtc-twl4030.c | 2 |
4 files changed, 164 insertions, 92 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index d5e4e637ddec..86c61f143515 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
| @@ -351,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
| 351 | /* register irq handler after we know what name we'll use */ | 351 | /* register irq handler after we know what name we'll use */ |
| 352 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | 352 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, |
| 353 | IRQF_DISABLED | IRQF_SHARED, | 353 | IRQF_DISABLED | IRQF_SHARED, |
| 354 | rtc->rtcdev->dev.bus_id, rtc); | 354 | dev_name(&rtc->rtcdev->dev), rtc); |
| 355 | if (ret) { | 355 | if (ret) { |
| 356 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | 356 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); |
| 357 | rtc_device_unregister(rtc->rtcdev); | 357 | rtc_device_unregister(rtc->rtcdev); |
| @@ -366,7 +366,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
| 366 | 366 | ||
| 367 | if (gpbr_readl(rtc) == 0) | 367 | if (gpbr_readl(rtc) == 0) |
| 368 | dev_warn(&pdev->dev, "%s: SET TIME!\n", | 368 | dev_warn(&pdev->dev, "%s: SET TIME!\n", |
| 369 | rtc->rtcdev->dev.bus_id); | 369 | dev_name(&rtc->rtcdev->dev)); |
| 370 | 370 | ||
| 371 | return 0; | 371 | return 0; |
| 372 | 372 | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 2cbeb0794f14..bd1ce8e2bc18 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
| @@ -377,13 +377,13 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
| 377 | 377 | ||
| 378 | /* handle periodic and alarm irqs */ | 378 | /* handle periodic and alarm irqs */ |
| 379 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, | 379 | if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, |
| 380 | rtc->dev.bus_id, rtc)) { | 380 | dev_name(&rtc->dev), rtc)) { |
| 381 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", | 381 | pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", |
| 382 | pdev->name, omap_rtc_timer); | 382 | pdev->name, omap_rtc_timer); |
| 383 | goto fail0; | 383 | goto fail0; |
| 384 | } | 384 | } |
| 385 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, | 385 | if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, |
| 386 | rtc->dev.bus_id, rtc)) { | 386 | dev_name(&rtc->dev), rtc)) { |
| 387 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", | 387 | pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", |
| 388 | pdev->name, omap_rtc_alarm); | 388 | pdev->name, omap_rtc_alarm); |
| 389 | goto fail1; | 389 | goto fail1; |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 1c3fc6b428e9..4898f7fe8518 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <asm/rtc.h> | 28 | #include <asm/rtc.h> |
| 29 | 29 | ||
| 30 | #define DRV_NAME "sh-rtc" | 30 | #define DRV_NAME "sh-rtc" |
| 31 | #define DRV_VERSION "0.2.0" | 31 | #define DRV_VERSION "0.2.1" |
| 32 | 32 | ||
| 33 | #define RTC_REG(r) ((r) * rtc_reg_size) | 33 | #define RTC_REG(r) ((r) * rtc_reg_size) |
| 34 | 34 | ||
| @@ -99,56 +99,51 @@ struct sh_rtc { | |||
| 99 | unsigned short periodic_freq; | 99 | unsigned short periodic_freq; |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | 102 | static int __sh_rtc_interrupt(struct sh_rtc *rtc) |
| 103 | { | 103 | { |
| 104 | struct sh_rtc *rtc = dev_id; | 104 | unsigned int tmp, pending; |
| 105 | unsigned int tmp; | ||
| 106 | |||
| 107 | spin_lock(&rtc->lock); | ||
| 108 | 105 | ||
| 109 | tmp = readb(rtc->regbase + RCR1); | 106 | tmp = readb(rtc->regbase + RCR1); |
| 107 | pending = tmp & RCR1_CF; | ||
| 110 | tmp &= ~RCR1_CF; | 108 | tmp &= ~RCR1_CF; |
| 111 | writeb(tmp, rtc->regbase + RCR1); | 109 | writeb(tmp, rtc->regbase + RCR1); |
| 112 | 110 | ||
| 113 | /* Users have requested One x Second IRQ */ | 111 | /* Users have requested One x Second IRQ */ |
| 114 | if (rtc->periodic_freq & PF_OXS) | 112 | if (pending && rtc->periodic_freq & PF_OXS) |
| 115 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); | 113 | rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); |
| 116 | 114 | ||
| 117 | spin_unlock(&rtc->lock); | 115 | return pending; |
| 118 | |||
| 119 | return IRQ_HANDLED; | ||
| 120 | } | 116 | } |
| 121 | 117 | ||
| 122 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | 118 | static int __sh_rtc_alarm(struct sh_rtc *rtc) |
| 123 | { | 119 | { |
| 124 | struct sh_rtc *rtc = dev_id; | 120 | unsigned int tmp, pending; |
| 125 | unsigned int tmp; | ||
| 126 | |||
| 127 | spin_lock(&rtc->lock); | ||
| 128 | 121 | ||
| 129 | tmp = readb(rtc->regbase + RCR1); | 122 | tmp = readb(rtc->regbase + RCR1); |
| 123 | pending = tmp & RCR1_AF; | ||
| 130 | tmp &= ~(RCR1_AF | RCR1_AIE); | 124 | tmp &= ~(RCR1_AF | RCR1_AIE); |
| 131 | writeb(tmp, rtc->regbase + RCR1); | 125 | writeb(tmp, rtc->regbase + RCR1); |
| 132 | |||
| 133 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
| 134 | 126 | ||
| 135 | spin_unlock(&rtc->lock); | 127 | if (pending) |
| 128 | rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); | ||
| 136 | 129 | ||
| 137 | return IRQ_HANDLED; | 130 | return pending; |
| 138 | } | 131 | } |
| 139 | 132 | ||
| 140 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | 133 | static int __sh_rtc_periodic(struct sh_rtc *rtc) |
| 141 | { | 134 | { |
| 142 | struct sh_rtc *rtc = dev_id; | ||
| 143 | struct rtc_device *rtc_dev = rtc->rtc_dev; | 135 | struct rtc_device *rtc_dev = rtc->rtc_dev; |
| 144 | unsigned int tmp; | 136 | struct rtc_task *irq_task; |
| 145 | 137 | unsigned int tmp, pending; | |
| 146 | spin_lock(&rtc->lock); | ||
| 147 | 138 | ||
| 148 | tmp = readb(rtc->regbase + RCR2); | 139 | tmp = readb(rtc->regbase + RCR2); |
| 140 | pending = tmp & RCR2_PEF; | ||
| 149 | tmp &= ~RCR2_PEF; | 141 | tmp &= ~RCR2_PEF; |
| 150 | writeb(tmp, rtc->regbase + RCR2); | 142 | writeb(tmp, rtc->regbase + RCR2); |
| 151 | 143 | ||
| 144 | if (!pending) | ||
| 145 | return 0; | ||
| 146 | |||
| 152 | /* Half period enabled than one skipped and the next notified */ | 147 | /* Half period enabled than one skipped and the next notified */ |
| 153 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) | 148 | if ((rtc->periodic_freq & PF_HP) && (rtc->periodic_freq & PF_COUNT)) |
| 154 | rtc->periodic_freq &= ~PF_COUNT; | 149 | rtc->periodic_freq &= ~PF_COUNT; |
| @@ -157,16 +152,65 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | |||
| 157 | rtc->periodic_freq |= PF_COUNT; | 152 | rtc->periodic_freq |= PF_COUNT; |
| 158 | if (rtc->periodic_freq & PF_KOU) { | 153 | if (rtc->periodic_freq & PF_KOU) { |
| 159 | spin_lock(&rtc_dev->irq_task_lock); | 154 | spin_lock(&rtc_dev->irq_task_lock); |
| 160 | if (rtc_dev->irq_task) | 155 | irq_task = rtc_dev->irq_task; |
| 161 | rtc_dev->irq_task->func(rtc_dev->irq_task->private_data); | 156 | if (irq_task) |
| 157 | irq_task->func(irq_task->private_data); | ||
| 162 | spin_unlock(&rtc_dev->irq_task_lock); | 158 | spin_unlock(&rtc_dev->irq_task_lock); |
| 163 | } else | 159 | } else |
| 164 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | 160 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); |
| 165 | } | 161 | } |
| 166 | 162 | ||
| 163 | return pending; | ||
| 164 | } | ||
| 165 | |||
| 166 | static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) | ||
| 167 | { | ||
| 168 | struct sh_rtc *rtc = dev_id; | ||
| 169 | int ret; | ||
| 170 | |||
| 171 | spin_lock(&rtc->lock); | ||
| 172 | ret = __sh_rtc_interrupt(rtc); | ||
| 173 | spin_unlock(&rtc->lock); | ||
| 174 | |||
| 175 | return IRQ_RETVAL(ret); | ||
| 176 | } | ||
| 177 | |||
| 178 | static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) | ||
| 179 | { | ||
| 180 | struct sh_rtc *rtc = dev_id; | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | spin_lock(&rtc->lock); | ||
| 184 | ret = __sh_rtc_alarm(rtc); | ||
| 185 | spin_unlock(&rtc->lock); | ||
| 186 | |||
| 187 | return IRQ_RETVAL(ret); | ||
| 188 | } | ||
| 189 | |||
| 190 | static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) | ||
| 191 | { | ||
| 192 | struct sh_rtc *rtc = dev_id; | ||
| 193 | int ret; | ||
| 194 | |||
| 195 | spin_lock(&rtc->lock); | ||
| 196 | ret = __sh_rtc_periodic(rtc); | ||
| 167 | spin_unlock(&rtc->lock); | 197 | spin_unlock(&rtc->lock); |
| 168 | 198 | ||
| 169 | return IRQ_HANDLED; | 199 | return IRQ_RETVAL(ret); |
| 200 | } | ||
| 201 | |||
| 202 | static irqreturn_t sh_rtc_shared(int irq, void *dev_id) | ||
| 203 | { | ||
| 204 | struct sh_rtc *rtc = dev_id; | ||
| 205 | int ret; | ||
| 206 | |||
| 207 | spin_lock(&rtc->lock); | ||
| 208 | ret = __sh_rtc_interrupt(rtc); | ||
| 209 | ret |= __sh_rtc_alarm(rtc); | ||
| 210 | ret |= __sh_rtc_periodic(rtc); | ||
| 211 | spin_unlock(&rtc->lock); | ||
| 212 | |||
| 213 | return IRQ_RETVAL(ret); | ||
| 170 | } | 214 | } |
| 171 | 215 | ||
| 172 | static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) | 216 | static inline void sh_rtc_setpie(struct device *dev, unsigned int enable) |
| @@ -275,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq) | |||
| 275 | return 0; | 319 | return 0; |
| 276 | } | 320 | } |
| 277 | 321 | ||
| 322 | static inline void sh_rtc_setcie(struct device *dev, unsigned int enable) | ||
| 323 | { | ||
| 324 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
| 325 | unsigned int tmp; | ||
| 326 | |||
| 327 | spin_lock_irq(&rtc->lock); | ||
| 328 | |||
| 329 | tmp = readb(rtc->regbase + RCR1); | ||
| 330 | |||
| 331 | if (!enable) | ||
| 332 | tmp &= ~RCR1_CIE; | ||
| 333 | else | ||
| 334 | tmp |= RCR1_CIE; | ||
| 335 | |||
| 336 | writeb(tmp, rtc->regbase + RCR1); | ||
| 337 | |||
| 338 | spin_unlock_irq(&rtc->lock); | ||
| 339 | } | ||
| 340 | |||
| 278 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 341 | static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
| 279 | { | 342 | { |
| 280 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 343 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
| @@ -291,9 +354,11 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
| 291 | break; | 354 | break; |
| 292 | case RTC_UIE_OFF: | 355 | case RTC_UIE_OFF: |
| 293 | rtc->periodic_freq &= ~PF_OXS; | 356 | rtc->periodic_freq &= ~PF_OXS; |
| 357 | sh_rtc_setcie(dev, 0); | ||
| 294 | break; | 358 | break; |
| 295 | case RTC_UIE_ON: | 359 | case RTC_UIE_ON: |
| 296 | rtc->periodic_freq |= PF_OXS; | 360 | rtc->periodic_freq |= PF_OXS; |
| 361 | sh_rtc_setcie(dev, 1); | ||
| 297 | break; | 362 | break; |
| 298 | case RTC_IRQP_READ: | 363 | case RTC_IRQP_READ: |
| 299 | ret = put_user(rtc->rtc_dev->irq_freq, | 364 | ret = put_user(rtc->rtc_dev->irq_freq, |
| @@ -356,18 +421,17 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
| 356 | tm->tm_sec--; | 421 | tm->tm_sec--; |
| 357 | #endif | 422 | #endif |
| 358 | 423 | ||
| 424 | /* only keep the carry interrupt enabled if UIE is on */ | ||
| 425 | if (!(rtc->periodic_freq & PF_OXS)) | ||
| 426 | sh_rtc_setcie(dev, 0); | ||
| 427 | |||
| 359 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | 428 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " |
| 360 | "mday=%d, mon=%d, year=%d, wday=%d\n", | 429 | "mday=%d, mon=%d, year=%d, wday=%d\n", |
| 361 | __func__, | 430 | __func__, |
| 362 | tm->tm_sec, tm->tm_min, tm->tm_hour, | 431 | tm->tm_sec, tm->tm_min, tm->tm_hour, |
| 363 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | 432 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); |
| 364 | 433 | ||
| 365 | if (rtc_valid_tm(tm) < 0) { | 434 | return rtc_valid_tm(tm); |
| 366 | dev_err(dev, "invalid date\n"); | ||
| 367 | rtc_time_to_tm(0, tm); | ||
| 368 | } | ||
| 369 | |||
| 370 | return 0; | ||
| 371 | } | 435 | } |
| 372 | 436 | ||
| 373 | static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) | 437 | static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) |
| @@ -572,7 +636,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 572 | { | 636 | { |
| 573 | struct sh_rtc *rtc; | 637 | struct sh_rtc *rtc; |
| 574 | struct resource *res; | 638 | struct resource *res; |
| 575 | unsigned int tmp; | 639 | struct rtc_time r; |
| 576 | int ret; | 640 | int ret; |
| 577 | 641 | ||
| 578 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); | 642 | rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); |
| @@ -585,26 +649,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 585 | ret = platform_get_irq(pdev, 0); | 649 | ret = platform_get_irq(pdev, 0); |
| 586 | if (unlikely(ret <= 0)) { | 650 | if (unlikely(ret <= 0)) { |
| 587 | ret = -ENOENT; | 651 | ret = -ENOENT; |
| 588 | dev_err(&pdev->dev, "No IRQ for period\n"); | 652 | dev_err(&pdev->dev, "No IRQ resource\n"); |
| 589 | goto err_badres; | 653 | goto err_badres; |
| 590 | } | 654 | } |
| 591 | rtc->periodic_irq = ret; | 655 | rtc->periodic_irq = ret; |
| 592 | 656 | rtc->carry_irq = platform_get_irq(pdev, 1); | |
| 593 | ret = platform_get_irq(pdev, 1); | 657 | rtc->alarm_irq = platform_get_irq(pdev, 2); |
| 594 | if (unlikely(ret <= 0)) { | ||
| 595 | ret = -ENOENT; | ||
| 596 | dev_err(&pdev->dev, "No IRQ for carry\n"); | ||
| 597 | goto err_badres; | ||
| 598 | } | ||
| 599 | rtc->carry_irq = ret; | ||
| 600 | |||
| 601 | ret = platform_get_irq(pdev, 2); | ||
| 602 | if (unlikely(ret <= 0)) { | ||
| 603 | ret = -ENOENT; | ||
| 604 | dev_err(&pdev->dev, "No IRQ for alarm\n"); | ||
| 605 | goto err_badres; | ||
| 606 | } | ||
| 607 | rtc->alarm_irq = ret; | ||
| 608 | 658 | ||
| 609 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 659 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 610 | if (unlikely(res == NULL)) { | 660 | if (unlikely(res == NULL)) { |
| @@ -646,47 +696,66 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) | |||
| 646 | } | 696 | } |
| 647 | 697 | ||
| 648 | rtc->rtc_dev->max_user_freq = 256; | 698 | rtc->rtc_dev->max_user_freq = 256; |
| 649 | rtc->rtc_dev->irq_freq = 1; | ||
| 650 | rtc->periodic_freq = 0x60; | ||
| 651 | 699 | ||
| 652 | platform_set_drvdata(pdev, rtc); | 700 | platform_set_drvdata(pdev, rtc); |
| 653 | 701 | ||
| 654 | /* register periodic/carry/alarm irqs */ | 702 | if (rtc->carry_irq <= 0) { |
| 655 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, IRQF_DISABLED, | 703 | /* register shared periodic/carry/alarm irq */ |
| 656 | "sh-rtc period", rtc); | 704 | ret = request_irq(rtc->periodic_irq, sh_rtc_shared, |
| 657 | if (unlikely(ret)) { | 705 | IRQF_DISABLED, "sh-rtc", rtc); |
| 658 | dev_err(&pdev->dev, | 706 | if (unlikely(ret)) { |
| 659 | "request period IRQ failed with %d, IRQ %d\n", ret, | 707 | dev_err(&pdev->dev, |
| 660 | rtc->periodic_irq); | 708 | "request IRQ failed with %d, IRQ %d\n", ret, |
| 661 | goto err_unmap; | 709 | rtc->periodic_irq); |
| 662 | } | 710 | goto err_unmap; |
| 711 | } | ||
| 712 | } else { | ||
| 713 | /* register periodic/carry/alarm irqs */ | ||
| 714 | ret = request_irq(rtc->periodic_irq, sh_rtc_periodic, | ||
| 715 | IRQF_DISABLED, "sh-rtc period", rtc); | ||
| 716 | if (unlikely(ret)) { | ||
| 717 | dev_err(&pdev->dev, | ||
| 718 | "request period IRQ failed with %d, IRQ %d\n", | ||
| 719 | ret, rtc->periodic_irq); | ||
| 720 | goto err_unmap; | ||
| 721 | } | ||
| 663 | 722 | ||
| 664 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, IRQF_DISABLED, | 723 | ret = request_irq(rtc->carry_irq, sh_rtc_interrupt, |
| 665 | "sh-rtc carry", rtc); | 724 | IRQF_DISABLED, "sh-rtc carry", rtc); |
| 666 | if (unlikely(ret)) { | 725 | if (unlikely(ret)) { |
| 667 | dev_err(&pdev->dev, | 726 | dev_err(&pdev->dev, |
| 668 | "request carry IRQ failed with %d, IRQ %d\n", ret, | 727 | "request carry IRQ failed with %d, IRQ %d\n", |
| 669 | rtc->carry_irq); | 728 | ret, rtc->carry_irq); |
| 670 | free_irq(rtc->periodic_irq, rtc); | 729 | free_irq(rtc->periodic_irq, rtc); |
| 671 | goto err_unmap; | 730 | goto err_unmap; |
| 672 | } | 731 | } |
| 673 | 732 | ||
| 674 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, IRQF_DISABLED, | 733 | ret = request_irq(rtc->alarm_irq, sh_rtc_alarm, |
| 675 | "sh-rtc alarm", rtc); | 734 | IRQF_DISABLED, "sh-rtc alarm", rtc); |
| 676 | if (unlikely(ret)) { | 735 | if (unlikely(ret)) { |
| 677 | dev_err(&pdev->dev, | 736 | dev_err(&pdev->dev, |
| 678 | "request alarm IRQ failed with %d, IRQ %d\n", ret, | 737 | "request alarm IRQ failed with %d, IRQ %d\n", |
| 679 | rtc->alarm_irq); | 738 | ret, rtc->alarm_irq); |
| 680 | free_irq(rtc->carry_irq, rtc); | 739 | free_irq(rtc->carry_irq, rtc); |
| 681 | free_irq(rtc->periodic_irq, rtc); | 740 | free_irq(rtc->periodic_irq, rtc); |
| 682 | goto err_unmap; | 741 | goto err_unmap; |
| 742 | } | ||
| 683 | } | 743 | } |
| 684 | 744 | ||
| 685 | tmp = readb(rtc->regbase + RCR1); | 745 | /* everything disabled by default */ |
| 686 | tmp &= ~RCR1_CF; | 746 | rtc->periodic_freq = 0; |
| 687 | tmp |= RCR1_CIE; | 747 | rtc->rtc_dev->irq_freq = 0; |
| 688 | writeb(tmp, rtc->regbase + RCR1); | 748 | sh_rtc_setpie(&pdev->dev, 0); |
| 749 | sh_rtc_setaie(&pdev->dev, 0); | ||
| 750 | sh_rtc_setcie(&pdev->dev, 0); | ||
| 751 | |||
| 752 | /* reset rtc to epoch 0 if time is invalid */ | ||
| 753 | if (rtc_read_time(rtc->rtc_dev, &r) < 0) { | ||
| 754 | rtc_time_to_tm(0, &r); | ||
| 755 | rtc_set_time(rtc->rtc_dev, &r); | ||
| 756 | } | ||
| 689 | 757 | ||
| 758 | device_init_wakeup(&pdev->dev, 1); | ||
| 690 | return 0; | 759 | return 0; |
| 691 | 760 | ||
| 692 | err_unmap: | 761 | err_unmap: |
| @@ -708,10 +777,13 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev) | |||
| 708 | 777 | ||
| 709 | sh_rtc_setpie(&pdev->dev, 0); | 778 | sh_rtc_setpie(&pdev->dev, 0); |
| 710 | sh_rtc_setaie(&pdev->dev, 0); | 779 | sh_rtc_setaie(&pdev->dev, 0); |
| 780 | sh_rtc_setcie(&pdev->dev, 0); | ||
| 711 | 781 | ||
| 712 | free_irq(rtc->carry_irq, rtc); | ||
| 713 | free_irq(rtc->periodic_irq, rtc); | 782 | free_irq(rtc->periodic_irq, rtc); |
| 714 | free_irq(rtc->alarm_irq, rtc); | 783 | if (rtc->carry_irq > 0) { |
| 784 | free_irq(rtc->carry_irq, rtc); | ||
| 785 | free_irq(rtc->alarm_irq, rtc); | ||
| 786 | } | ||
| 715 | 787 | ||
| 716 | release_resource(rtc->res); | 788 | release_resource(rtc->res); |
| 717 | 789 | ||
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c index ad35f76c46b7..a6341e4f9a0f 100644 --- a/drivers/rtc/rtc-twl4030.c +++ b/drivers/rtc/rtc-twl4030.c | |||
| @@ -426,7 +426,7 @@ static int __devinit twl4030_rtc_probe(struct platform_device *pdev) | |||
| 426 | 426 | ||
| 427 | ret = request_irq(irq, twl4030_rtc_interrupt, | 427 | ret = request_irq(irq, twl4030_rtc_interrupt, |
| 428 | IRQF_TRIGGER_RISING, | 428 | IRQF_TRIGGER_RISING, |
| 429 | rtc->dev.bus_id, rtc); | 429 | dev_name(&rtc->dev), rtc); |
| 430 | if (ret < 0) { | 430 | if (ret < 0) { |
| 431 | dev_err(&pdev->dev, "IRQ is not free.\n"); | 431 | dev_err(&pdev->dev, "IRQ is not free.\n"); |
| 432 | goto out1; | 432 | goto out1; |
