aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-sh.c')
-rw-r--r--drivers/rtc/rtc-sh.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index aeff25111979..21e7435daecb 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -319,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
319 return 0; 319 return 0;
320} 320}
321 321
322static 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
322static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 341static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
323{ 342{
324 struct sh_rtc *rtc = dev_get_drvdata(dev); 343 struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -335,9 +354,11 @@ static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
335 break; 354 break;
336 case RTC_UIE_OFF: 355 case RTC_UIE_OFF:
337 rtc->periodic_freq &= ~PF_OXS; 356 rtc->periodic_freq &= ~PF_OXS;
357 sh_rtc_setcie(dev, 0);
338 break; 358 break;
339 case RTC_UIE_ON: 359 case RTC_UIE_ON:
340 rtc->periodic_freq |= PF_OXS; 360 rtc->periodic_freq |= PF_OXS;
361 sh_rtc_setcie(dev, 1);
341 break; 362 break;
342 case RTC_IRQP_READ: 363 case RTC_IRQP_READ:
343 ret = put_user(rtc->rtc_dev->irq_freq, 364 ret = put_user(rtc->rtc_dev->irq_freq,
@@ -400,6 +421,10 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
400 tm->tm_sec--; 421 tm->tm_sec--;
401#endif 422#endif
402 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
403 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, "
404 "mday=%d, mon=%d, year=%d, wday=%d\n", 429 "mday=%d, mon=%d, year=%d, wday=%d\n",
405 __func__, 430 __func__,
@@ -616,7 +641,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
616{ 641{
617 struct sh_rtc *rtc; 642 struct sh_rtc *rtc;
618 struct resource *res; 643 struct resource *res;
619 unsigned int tmp;
620 int ret; 644 int ret;
621 645
622 rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL); 646 rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
@@ -676,8 +700,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
676 } 700 }
677 701
678 rtc->rtc_dev->max_user_freq = 256; 702 rtc->rtc_dev->max_user_freq = 256;
679 rtc->rtc_dev->irq_freq = 1;
680 rtc->periodic_freq = 0x60;
681 703
682 platform_set_drvdata(pdev, rtc); 704 platform_set_drvdata(pdev, rtc);
683 705
@@ -724,11 +746,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
724 } 746 }
725 } 747 }
726 748
727 tmp = readb(rtc->regbase + RCR1); 749 /* everything disabled by default */
728 tmp &= ~RCR1_CF; 750 rtc->periodic_freq = 0;
729 tmp |= RCR1_CIE; 751 rtc->rtc_dev->irq_freq = 0;
730 writeb(tmp, rtc->regbase + RCR1); 752 sh_rtc_setpie(&pdev->dev, 0);
731 753 sh_rtc_setaie(&pdev->dev, 0);
754 sh_rtc_setcie(&pdev->dev, 0);
732 return 0; 755 return 0;
733 756
734err_unmap: 757err_unmap:
@@ -750,6 +773,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
750 773
751 sh_rtc_setpie(&pdev->dev, 0); 774 sh_rtc_setpie(&pdev->dev, 0);
752 sh_rtc_setaie(&pdev->dev, 0); 775 sh_rtc_setaie(&pdev->dev, 0);
776 sh_rtc_setcie(&pdev->dev, 0);
753 777
754 free_irq(rtc->periodic_irq, rtc); 778 free_irq(rtc->periodic_irq, rtc);
755 if (rtc->carry_irq > 0) { 779 if (rtc->carry_irq > 0) {