diff options
author | Preetham Chandru <pchandru@nvidia.com> | 2012-05-08 19:56:27 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-05-15 15:12:19 -0700 |
commit | d03e84c4d981d65d7b7e68322ce02157c7e7a6c7 (patch) | |
tree | 39896e15d67643cef86250f686b19e6016011cdb | |
parent | b21def416c5850657ea7a366b8eb5dbb3a562452 (diff) |
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 <pchandru@nvidia.com>
Change-Id: Ia35192e691ca116b13093f52873020f67c5c2f8d
Reviewed-on: http://git-master/r/101447
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
-rw-r--r-- | drivers/rtc/rtc-tps6591x.c | 82 |
1 files 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, |