summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2010-09-09 11:46:18 -0700
committerVarun Colbert <vcolbert@nvidia.com>2010-10-26 15:03:36 -0700
commit35e97aa59eaa0cc7233c100edc0aa3e7b4e1605e (patch)
tree743512854b2ce749bd92eb09c6ae52688b8ff1a8 /drivers
parentdc9cea61b3333432d6c1d2003a1bdb9ce055f04a (diff)
[arm/tegra] support RTC alarm interrupt in odm_kit
New API added to odm_kit to register a callback to use on RTC interrupt. Supported added for RTC alarms in the max8907b PMU. Bug 717253 Bug 734529 Change-Id: I34abebd7dd3caf4ef8923fcf651c50f6d245f6b4 Reviewed-on: http://git-master/r/7328 Reviewed-by: Krishna Reddy <vdumpa@nvidia.com> Reviewed-by: Jonathan Mayo <jmayo@nvidia.com> Tested-by: Jonathan Mayo <jmayo@nvidia.com> Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com> Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rtc/rtc-tegra-odm.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/drivers/rtc/rtc-tegra-odm.c b/drivers/rtc/rtc-tegra-odm.c
index 2a90d60b06b8..8a1c55737bfb 100644
--- a/drivers/rtc/rtc-tegra-odm.c
+++ b/drivers/rtc/rtc-tegra-odm.c
@@ -21,6 +21,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#define NV_DEBUG 0
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
@@ -31,10 +32,14 @@
#include <linux/platform_device.h>
#include "nvodm_pmu.h"
-#define PMU_IOCTL_ENABLE 1
-
/* Create a custom rtc structrue and move this to that structure */
static NvOdmPmuDeviceHandle hPmu = NULL;
+static struct platform_device *tegra_rtc_pdev = NULL;
+
+static int tegra_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
@@ -71,7 +76,6 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm)
return 0;
}
-#if (PMU_IOCTL_ENABLE)
static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
{
@@ -93,9 +97,14 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
NvU32 alarm_sec;
struct rtc_time now_time;
+ printk("%s(): wkalrm->enabled=%d\n", __func__, wkalrm?wkalrm->enabled:-1);
+
pr_debug("wkalrm->enabled = %d\n", wkalrm->enabled);
- if (wkalrm->enabled == 0)
+ if (wkalrm->enabled == 0) {
+ if(!NvOdmPmuWriteAlarm(hPmu, 0))
+ return -EINVAL;
return 0;
+ }
if (!NvOdmPmuReadRtc(hPmu, &now)) {
pr_debug("NvOdmPmuReadRtc failed\n");
@@ -119,20 +128,43 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
pr_debug("alarm_sec = %u\n", alarm_sec);
- if(!NvOdmPmuWriteAlarm(hPmu, alarm_sec-now))
+ if(!NvOdmPmuWriteAlarm(hPmu, alarm_sec))
return -EINVAL;
return 0;
}
-#endif
+
+static NvBool tegra_rtc_alarm_interrupt(NvOdmPmuDeviceHandle hPmu) {
+ unsigned long events = 0;
+ struct rtc_device *rtc;
+
+ rtc = tegra_rtc_pdev ? platform_get_drvdata(tegra_rtc_pdev) : NULL;
+
+ pr_info("%s():enter.\n", __func__);
+
+ /* Alarm set */
+ events |= RTC_IRQF | RTC_AF;
+
+ if (rtc)
+ rtc_update_irq(rtc, 1, events);
+
+ return NV_TRUE;
+}
+
+static int tegra_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+ if (!dev || !dev->driver)
+ return 0;
+ return seq_printf(seq, "name\t\t: %s\n", dev_name(dev));
+}
static struct rtc_class_ops tegra_rtc_ops = {
+ .ioctl = tegra_rtc_ioctl,
.read_time = tegra_rtc_read_time,
.set_time = tegra_rtc_set_time,
-#if (PMU_IOCTL_ENABLE)
.read_alarm = tegra_rtc_read_alarm,
.set_alarm = tegra_rtc_set_alarm,
-#endif
+ .proc = tegra_rtc_proc,
};
static int __init tegra_rtc_probe(struct platform_device *pdev)
@@ -156,6 +188,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
return -EINVAL;
}
+ device_init_wakeup(&pdev->dev, 1);
rtc = rtc_device_register(pdev->name, &pdev->dev,
&tegra_rtc_ops, THIS_MODULE);
@@ -168,6 +201,10 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, rtc);
+ tegra_rtc_pdev = pdev;
+
+ NvOdmPmuAlarmHandlerSet(hPmu, tegra_rtc_alarm_interrupt);
+
return 0;
}
@@ -183,11 +220,15 @@ static int __exit tegra_rtc_remove(struct platform_device *pdev)
static int tegra_rtc_suspend(struct platform_device *pdev, pm_message_t state)
{
+ NvOdmPmuSuspendRtc(hPmu);
+
return 0;
}
static int tegra_rtc_resume(struct platform_device *pdev)
{
+ NvOdmPmuResumeRtc(hPmu);
+
return 0;
}