From 8e54b0be46469bd3c0b985aab0c14199bcf825f4 Mon Sep 17 00:00:00 2001 From: venu byravarasu Date: Mon, 11 Apr 2011 17:43:05 +0530 Subject: 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 Reviewed-by: Laxman Dewangan Original-Change-Id: I68bb747cb965d14af9918ad6086ac2e9888f7136 Rebase-Id: Ra2e528aeb4727392e17ee911d673cc49e9d03068 --- drivers/rtc/rtc-tps6591x.c | 68 ++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 29 deletions(-) mode change 100644 => 100755 drivers/rtc/rtc-tps6591x.c (limited to 'drivers') diff --git a/drivers/rtc/rtc-tps6591x.c b/drivers/rtc/rtc-tps6591x.c old mode 100644 new mode 100755 index 9d3fe9677f6c..a304d4684b7e --- 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"); @@ -401,7 +420,7 @@ static int __devinit tps6591x_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "\n no IRQ specified, wakeup is disabled\n"); dev_set_drvdata(&pdev->dev, rtc); - 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)) { @@ -419,20 +438,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"); -- cgit v1.2.3