aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sh.c
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2009-03-19 06:05:58 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-03-20 05:56:50 -0400
commit9cd88b90a6008b0d744187fab80ade4c81c6536f (patch)
treea790ecb0cf2e5a45d4047221fb38a54fbb5533a9 /drivers/rtc/rtc-sh.c
parent615e73b3cd8876262f61ea28b4147c8de38a043a (diff)
sh: sh-rtc carry interrupt rework
This patch modifies the SuperH RTC driver to only enable carry interrupts when needed. So by default no interrupts are enabled with this patch. Without this patch a suspending system will most likely wake up by the carry interrupt regardless if the alarm interrupt has been enabled or not. Signed-off-by: Magnus Damm <damm@igel.co.jp> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
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) {