diff options
author | venu byravarasu <vbyravarasu@nvidia.com> | 2011-04-11 17:43:05 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-04-26 15:55:34 -0700 |
commit | 69419be9fd71d2b3a76d3e5f7200eceacefa1bed (patch) | |
tree | 3afd2951cd5ad728e2c2e2ec616f9ed3ddd7e47c /drivers/rtc | |
parent | 37eeaf16e6c5a7fdbdea94c72291b64b55b92c89 (diff) |
rtc: tps6591x: wake up from suspend on alarm
Changes required for waking up system, when RTC alarm
is triggered.
bug 793949
Original-Change-Id: Idcc536a819e977fe35bafeebdffddf57d5388f21
Reviewed-on: http://git-master/r/27359
Tested-by: Venu Byravarasu <vbyravarasu@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Change-Id: I68bb747cb965d14af9918ad6086ac2e9888f7136
Diffstat (limited to 'drivers/rtc')
-rwxr-xr-x[-rw-r--r--] | drivers/rtc/rtc-tps6591x.c | 68 |
1 files changed, 39 insertions, 29 deletions
diff --git a/drivers/rtc/rtc-tps6591x.c b/drivers/rtc/rtc-tps6591x.c index 3513fc3a31c4..8b69f61055f1 100644..100755 --- a/drivers/rtc/rtc-tps6591x.c +++ b/drivers/rtc/rtc-tps6591x.c @@ -1,5 +1,5 @@ /* - * drivers/rtc/rtc-tps6591x.c + * drivers/rtc/rtc_tps6591x.c * * RTC driver for TI TPS6591x * @@ -37,9 +37,12 @@ #define RTC_SECONDS_REG 0x0 #define RTC_ALARM 0x8 #define RTC_INT 0x12 -#define RTC_INT_MASK 0x51 #define RTC_RESET_STATUS 0x16 +#define ENABLE_ALARM_INT 0x8 +#define RTC_RESET_VALUE 0x80 +#define ALARM_INT_STATUS 0x40 + struct tps6591x_rtc { unsigned long epoch_start; int irq; @@ -51,6 +54,16 @@ static int tps6591x_read_regs(struct device *dev, int reg, int len, uint8_t *val) { int ret; + + /* dummy read of STATUS_REG as per data sheet */ + ret = tps6591x_reads(dev->parent, RTC_STATUS, 1, val); + if (ret < 0) { + dev_err(dev->parent, "\n %s failed reading from RTC_STATUS\n", + __func__); + WARN_ON(1); + return ret; + } + ret = tps6591x_reads(dev->parent, reg, len, val); if (ret < 0) { dev_err(dev->parent, "\n %s failed reading from 0x%02x\n", @@ -77,7 +90,7 @@ static int tps6591x_write_regs(struct device *dev, int reg, int len, static int tps6591x_rtc_valid_tm(struct rtc_time *tm) { - if (tm->tm_year <= 99 + if (tm->tm_year > 99 || ((unsigned)tm->tm_mon) >= 12 || tm->tm_mday < 1 || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900) @@ -112,9 +125,9 @@ static void convert_decimal_to_bcd(u8 *buf, u8 len) buf[i] = dec2bcd(buf[i]); } -static void print_time(struct rtc_time *tm) +static void print_time(struct device *dev, struct rtc_time *tm) { - printk(KERN_INFO "\n TPS6591x RTC Time : %d-%d-%d %d:%d:%d\n", + dev_info(dev, "RTC Time : %d-%d-%d %d:%d:%d\n", tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_hour, tm->tm_min , tm->tm_sec); } @@ -136,7 +149,7 @@ static int tps6591x_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mon = buff[4]; tm->tm_year = buff[5]; tm->tm_wday = buff[6]; - print_time(tm); + print_time(dev, tm); return tps6591x_rtc_valid_tm(tm); } @@ -225,7 +238,7 @@ static int tps6591x_rtc_set_time(struct device *dev, struct rtc_time *tm) buff[5] = tm->tm_year; buff[6] = tm->tm_wday; - print_time(tm); + print_time(dev, tm); convert_decimal_to_bcd(buff, sizeof(buff)); err = tps6591x_rtc_stop(dev); if (err < 0) { @@ -260,7 +273,7 @@ static int tps6591x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) return -EIO; dev_info(dev->parent, "\n setting alarm to requested time::\n"); - print_time(&alrm->time); + print_time(dev->parent, &alrm->time); rtc_tm_to_time(&alrm->time, &seconds); tps6591x_rtc_read_time(dev, &tm); rtc_tm_to_time(&tm, &rtc->epoch_start); @@ -310,7 +323,7 @@ static int tps6591x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->time.tm_year = buff[5]; dev_info(dev->parent, "\n getting alarm time::\n"); - print_time(&alrm->time); + print_time(dev, &alrm->time); return 0; } @@ -366,8 +379,14 @@ static irqreturn_t tps6591x_rtc_irq(int irq, void *data) u8 reg; int err; - /* clear Alarm stray interrupt and Power_up status bits.*/ - reg = 0xC0; + /* clear Alarm status bits.*/ + err = tps6591x_read_regs(dev, RTC_STATUS, 1, ®); + if (err) { + dev_err(dev->parent, "unable to read RTC_STATUS reg\n"); + return -EBUSY; + } + + reg = ALARM_INT_STATUS; err = tps6591x_write_regs(dev, RTC_STATUS, 1, ®); if (err) { dev_err(dev->parent, "unable to program RTC_STATUS reg\n"); @@ -400,7 +419,7 @@ static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) if (pdata->irq < 0) dev_err(&pdev->dev, "\n no IRQ specified, wakeup is disabled\n"); - rtc->rtc = rtc_device_register("rtc-tps6591x", &pdev->dev, + rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, &tps6591x_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc)) { @@ -418,20 +437,12 @@ static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "\n %s unable to read status\n", __func__); return -EBUSY; } - if (reg & 0x80) - dev_info(&pdev->dev, "\n %s RTC reset occured\n", __func__); - /* cear Alarm stray interrupt and Power_up status bits.*/ - reg = 0xC0; - tps6591x_write_regs(&pdev->dev, RTC_STATUS, 1, ®); - if (err) { - dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n"); - return -EBUSY; - } + if (reg & RTC_RESET_VALUE) + dev_info(&pdev->dev, "\n %s RTC reset occured\n", __func__); - /* enable ALARM INT only */ - reg = 0xBF; - tps6591x_write_regs(&pdev->dev, RTC_INT_MASK, 1, ®); + reg = ENABLE_ALARM_INT; + tps6591x_write_regs(&pdev->dev, RTC_INT, 1, ®); if (err) { dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n"); return -EBUSY; @@ -441,15 +452,14 @@ static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) if (pdata && (pdata->irq >= 0)) { rtc->irq = pdata->irq; err = request_threaded_irq(pdata->irq, NULL, tps6591x_rtc_irq, - IRQF_ONESHOT, "rtc-tps6591x", - &pdev->dev); + IRQF_ONESHOT, "rtc_tps6591x", + &pdev->dev); if (err) { dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq); rtc->irq = -1; } else { device_init_wakeup(&pdev->dev, 1); enable_irq_wake(rtc->irq); - disable_irq(rtc->irq); } } return 0; @@ -474,7 +484,7 @@ static int __devexit tps6591x_rtc_remove(struct platform_device *pdev) static struct platform_driver tps6591x_rtc_driver = { .driver = { - .name = "rtc-tps6591x", + .name = "rtc_tps6591x", .owner = THIS_MODULE, }, .probe = tps6591x_rtc_probe, @@ -496,4 +506,4 @@ module_exit(tps6591x_rtc_exit); MODULE_DESCRIPTION("TI TPS6591x RTC driver"); MODULE_AUTHOR("NVIDIA Corporation"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:rtc-tps6591x") +MODULE_ALIAS("platform:rtc_tps6591x") |