From d03e84c4d981d65d7b7e68322ce02157c7e7a6c7 Mon Sep 17 00:00:00 2001 From: Preetham Chandru Date: Tue, 8 May 2012 19:56:27 +0530 Subject: rtc: tps6591x: Enable alarm interrupt for RTC_WKALM_SET ioctl RTC_WKALM_SET ioctl should do two things: 1. Set alarm value 2. Enable alarm irq In the current implementation for RTC_WKALM_SET ioctl we are only setting the alarm value but not enabling the alarm irq and hence the system is not waking from lp0 state once the set alarm value expiries. For RTC_WKALM_SET ioctl, alarm->enabled will be set to one from userspace. So based on this condition we can differentiate between RTC_WKALM_SET & RTC_ALM_SET and accordingly enable alarm irq. Bug 978205 Signed-off-by: Preetham Chandru R Change-Id: Ia35192e691ca116b13093f52873020f67c5c2f8d Reviewed-on: http://git-master/r/101447 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Varun Wadekar --- drivers/rtc/rtc-tps6591x.c | 82 +++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/rtc/rtc-tps6591x.c b/drivers/rtc/rtc-tps6591x.c index cab3e8874dff..6223f1108f06 100644 --- a/drivers/rtc/rtc-tps6591x.c +++ b/drivers/rtc/rtc-tps6591x.c @@ -3,7 +3,7 @@ * * RTC driver for TI TPS6591x * - * Copyright (c) 2011, NVIDIA Corporation. + * Copyright (c) 2011-2012, NVIDIA Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -276,6 +276,42 @@ static int tps6591x_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } +static int tps6591x_rtc_alarm_irq_enable(struct device *dev, + unsigned int enable) +{ + struct tps6591x_rtc *rtc = dev_get_drvdata(dev); + u8 reg; + int err; + + if (rtc->irq == -1) + return -EIO; + + if (enable) { + if (rtc->irq_en == true) + return 0; + err = tps6591x_read_regs(dev, RTC_INT, 1, ®); + if (err) + return err; + reg |= 0x8; + err = tps6591x_write_regs(dev, RTC_INT, 1, ®); + if (err) + return err; + rtc->irq_en = true; + } else { + if (rtc->irq_en == false) + return 0; + err = tps6591x_read_regs(dev, RTC_INT, 1, ®); + if (err) + return err; + reg &= ~0x8; + err = tps6591x_write_regs(dev, RTC_INT, 1, ®); + if (err) + return err; + rtc->irq_en = false; + } + return 0; +} + static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct tps6591x_rtc *rtc = dev_get_drvdata(dev); @@ -298,10 +334,10 @@ static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return -EINVAL; } - if (alrm->enabled && !rtc->irq_en) { - rtc->irq_en = true; - } else if (!alrm->enabled && rtc->irq_en) { - rtc->irq_en = false; + err = tps6591x_rtc_alarm_irq_enable(dev, alrm->enabled); + if(err) { + dev_err(dev->parent, "\n can't set alarm irq\n"); + return err; } buff[0] = alrm->time.tm_sec; @@ -341,42 +377,6 @@ static int tps6591x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) return 0; } -static int tps6591x_rtc_alarm_irq_enable(struct device *dev, - unsigned int enable) -{ - struct tps6591x_rtc *rtc = dev_get_drvdata(dev); - u8 reg; - int err; - - if (rtc->irq == -1) - return -EIO; - - if (enable) { - if (rtc->irq_en == true) - return 0; - err = tps6591x_read_regs(dev, RTC_INT, 1, ®); - if (err) - return err; - reg |= 0x8; - err = tps6591x_write_regs(dev, RTC_INT, 1, ®); - if (err) - return err; - rtc->irq_en = true; - } else { - if (rtc->irq_en == false) - return 0; - err = tps6591x_read_regs(dev, RTC_INT, 1, ®); - if (err) - return err; - reg &= ~0x8; - err = tps6591x_write_regs(dev, RTC_INT, 1, ®); - if (err) - return err; - rtc->irq_en = false; - } - return 0; -} - static const struct rtc_class_ops tps6591x_rtc_ops = { .read_time = tps6591x_rtc_read_time, .set_time = tps6591x_rtc_set_time, -- cgit v1.2.3