mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 08:44:14 +08:00
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>
This commit is contained in:
parent
615e73b3cd
commit
9cd88b90a6
@ -319,6 +319,25 @@ static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void sh_rtc_setcie(struct device *dev, unsigned int enable)
|
||||||
|
{
|
||||||
|
struct sh_rtc *rtc = dev_get_drvdata(dev);
|
||||||
|
unsigned int tmp;
|
||||||
|
|
||||||
|
spin_lock_irq(&rtc->lock);
|
||||||
|
|
||||||
|
tmp = readb(rtc->regbase + RCR1);
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
|
tmp &= ~RCR1_CIE;
|
||||||
|
else
|
||||||
|
tmp |= RCR1_CIE;
|
||||||
|
|
||||||
|
writeb(tmp, rtc->regbase + RCR1);
|
||||||
|
|
||||||
|
spin_unlock_irq(&rtc->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
static int sh_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct sh_rtc *rtc = dev_get_drvdata(dev);
|
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)
|
|||||||
break;
|
break;
|
||||||
case RTC_UIE_OFF:
|
case RTC_UIE_OFF:
|
||||||
rtc->periodic_freq &= ~PF_OXS;
|
rtc->periodic_freq &= ~PF_OXS;
|
||||||
|
sh_rtc_setcie(dev, 0);
|
||||||
break;
|
break;
|
||||||
case RTC_UIE_ON:
|
case RTC_UIE_ON:
|
||||||
rtc->periodic_freq |= PF_OXS;
|
rtc->periodic_freq |= PF_OXS;
|
||||||
|
sh_rtc_setcie(dev, 1);
|
||||||
break;
|
break;
|
||||||
case RTC_IRQP_READ:
|
case RTC_IRQP_READ:
|
||||||
ret = put_user(rtc->rtc_dev->irq_freq,
|
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)
|
|||||||
tm->tm_sec--;
|
tm->tm_sec--;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* only keep the carry interrupt enabled if UIE is on */
|
||||||
|
if (!(rtc->periodic_freq & PF_OXS))
|
||||||
|
sh_rtc_setcie(dev, 0);
|
||||||
|
|
||||||
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
|
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
|
||||||
"mday=%d, mon=%d, year=%d, wday=%d\n",
|
"mday=%d, mon=%d, year=%d, wday=%d\n",
|
||||||
__func__,
|
__func__,
|
||||||
@ -616,7 +641,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct sh_rtc *rtc;
|
struct sh_rtc *rtc;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
unsigned int tmp;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
|
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
|
||||||
@ -676,8 +700,6 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtc->rtc_dev->max_user_freq = 256;
|
rtc->rtc_dev->max_user_freq = 256;
|
||||||
rtc->rtc_dev->irq_freq = 1;
|
|
||||||
rtc->periodic_freq = 0x60;
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, rtc);
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
|
||||||
@ -724,11 +746,12 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = readb(rtc->regbase + RCR1);
|
/* everything disabled by default */
|
||||||
tmp &= ~RCR1_CF;
|
rtc->periodic_freq = 0;
|
||||||
tmp |= RCR1_CIE;
|
rtc->rtc_dev->irq_freq = 0;
|
||||||
writeb(tmp, rtc->regbase + RCR1);
|
sh_rtc_setpie(&pdev->dev, 0);
|
||||||
|
sh_rtc_setaie(&pdev->dev, 0);
|
||||||
|
sh_rtc_setcie(&pdev->dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_unmap:
|
err_unmap:
|
||||||
@ -750,6 +773,7 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
|
|||||||
|
|
||||||
sh_rtc_setpie(&pdev->dev, 0);
|
sh_rtc_setpie(&pdev->dev, 0);
|
||||||
sh_rtc_setaie(&pdev->dev, 0);
|
sh_rtc_setaie(&pdev->dev, 0);
|
||||||
|
sh_rtc_setcie(&pdev->dev, 0);
|
||||||
|
|
||||||
free_irq(rtc->periodic_irq, rtc);
|
free_irq(rtc->periodic_irq, rtc);
|
||||||
if (rtc->carry_irq > 0) {
|
if (rtc->carry_irq > 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user