X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Frtc%2Frtc-vr41xx.c;h=af7596ef29e2d837f2c9c8ea6b6d4fc7b7d37102;hb=1e27dbe7746f3bcbcf1f9a37f31df4b886e36ce3;hp=596764fd29f5a320cfeb89a4fb0823cac3972720;hpb=4bf311ddfbffe12d41ad1a3c311ab727db6f72cb;p=powerpc.git diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c index 596764fd29..af7596ef29 100644 --- a/drivers/rtc/rtc-vr41xx.c +++ b/drivers/rtc/rtc-vr41xx.c @@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(rtc_lock); static char rtc_name[] = "RTC"; static unsigned long periodic_frequency; static unsigned long periodic_count; +static unsigned int alarm_enabled; struct resource rtc_resource[2] = { { .name = rtc_name, @@ -188,6 +189,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) low = rtc1_read(ECMPLREG); mid = rtc1_read(ECMPMREG); high = rtc1_read(ECMPHREG); + wkalrm->enabled = alarm_enabled; spin_unlock_irq(&rtc_lock); @@ -206,10 +208,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) spin_lock_irq(&rtc_lock); + if (alarm_enabled) + disable_irq(ELAPSEDTIME_IRQ); + rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); + if (wkalrm->enabled) + enable_irq(ELAPSEDTIME_IRQ); + + alarm_enabled = wkalrm->enabled; + spin_unlock_irq(&rtc_lock); return 0; @@ -221,10 +231,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long switch (cmd) { case RTC_AIE_ON: - enable_irq(ELAPSEDTIME_IRQ); + spin_lock_irq(&rtc_lock); + + if (!alarm_enabled) { + enable_irq(ELAPSEDTIME_IRQ); + alarm_enabled = 1; + } + + spin_unlock_irq(&rtc_lock); break; case RTC_AIE_OFF: - disable_irq(ELAPSEDTIME_IRQ); + spin_lock_irq(&rtc_lock); + + if (alarm_enabled) { + disable_irq(ELAPSEDTIME_IRQ); + alarm_enabled = 0; + } + + spin_unlock_irq(&rtc_lock); break; case RTC_PIE_ON: enable_irq(RTCLONG1_IRQ); @@ -268,19 +292,19 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long return 0; } -static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) { struct platform_device *pdev = (struct platform_device *)dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); rtc2_write(RTCINTREG, ELAPSEDTIME_INT); - rtc_update_irq(&rtc->class_dev, 1, RTC_AF); + rtc_update_irq(rtc, 1, RTC_AF); return IRQ_HANDLED; } -static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t rtclong1_interrupt(int irq, void *dev_id) { struct platform_device *pdev = (struct platform_device *)dev_id; struct rtc_device *rtc = platform_get_drvdata(pdev); @@ -291,12 +315,12 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id, struct pt_regs *reg rtc1_write(RTCL1LREG, count); rtc1_write(RTCL1HREG, count >> 16); - rtc_update_irq(&rtc->class_dev, 1, RTC_PF); + rtc_update_irq(rtc, 1, RTC_PF); return IRQ_HANDLED; } -static struct rtc_class_ops vr41xx_rtc_ops = { +static const struct rtc_class_ops vr41xx_rtc_ops = { .release = vr41xx_rtc_release, .ioctl = vr41xx_rtc_ioctl, .read_time = vr41xx_rtc_read_time,