[PATCH 2/2] rtc: omap: add rtc wakeup support to alarm events
Hebbar Gururaja
gururaja.hebbar at ti.com
Fri May 31 02:33:25 EDT 2013
On some platforms (like AM33xx), a special register (RTC_IRQWAKEEN)
is available to enable Wakeup feature for Alarm Events.
Since new platforms/Boards are now added through DT only, this feature
is supported via DT property only.
Platforms using such IP should add the property "ti,has_irq_wake_enb"
in rtc DT node.
Signed-off-by: Hebbar Gururaja <gururaja.hebbar at ti.com>
---
:100644 100644 108a629... b870d87... M Documentation/devicetree/bindings/rtc/rtc-omap.txt
:100644 100644 000a02f... 5e9c0dd... M drivers/rtc/rtc-omap.c
Documentation/devicetree/bindings/rtc/rtc-omap.txt | 2 +
drivers/rtc/rtc-omap.c | 47 ++++++++++++++++----
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/Documentation/devicetree/bindings/rtc/rtc-omap.txt b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
index 108a629..b870d87 100644
--- a/Documentation/devicetree/bindings/rtc/rtc-omap.txt
+++ b/Documentation/devicetree/bindings/rtc/rtc-omap.txt
@@ -9,6 +9,8 @@ Required properties:
Optional properties:
- ti,wakeup_capable: Inform the rtc driver that this module is wake-up
capable so that rtcwake and suspend tests can work.
+- ti,has_irq_wake_enb: Inform rtc driver that this module has a a
+ special register to enable Wakeup feature for Alarm events.
Example:
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 000a02f..5e9c0dd 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -72,6 +72,8 @@
#define OMAP_RTC_KICK0_REG 0x6c
#define OMAP_RTC_KICK1_REG 0x70
+#define OMAP_RTC_IRQWAKEEN 0x7C
+
/* OMAP_RTC_CTRL_REG bit fields: */
#define OMAP_RTC_CTRL_SPLIT (1<<7)
#define OMAP_RTC_CTRL_DISABLE (1<<6)
@@ -96,6 +98,9 @@
#define OMAP_RTC_INTERRUPTS_IT_ALARM (1<<3)
#define OMAP_RTC_INTERRUPTS_IT_TIMER (1<<2)
+/* OMAP_RTC_IRQWAKEEN bit fields: */
+#define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN (1<<1)
+
/* OMAP_RTC_KICKER values */
#define KICK0_VALUE 0x83e70b13
#define KICK1_VALUE 0x95a4f1e0
@@ -103,6 +108,7 @@
#define OMAP_RTC_HAS_KICKER 0x1
static void __iomem *rtc_base;
+static unsigned int has_irq_wake_enb_bit;
#define rtc_read(addr) readb(rtc_base + (addr))
#define rtc_write(val, addr) writeb(val, rtc_base + (addr))
@@ -425,9 +431,14 @@ static int __init omap_rtc_probe(struct platform_device *pdev)
/* Fixup wakeup-enable feature based on the device tree */
if (of_id && of_find_property(pdev->dev.of_node,
- "ti,wakeup_capable", NULL))
+ "ti,wakeup_capable", NULL)) {
device_init_wakeup(&pdev->dev, 1);
+ if (of_find_property(pdev->dev.of_node,
+ "ti,has_irq_wake_enb", NULL))
+ has_irq_wake_enb_bit = true;
+ }
+
if (new_ctrl & (u8) OMAP_RTC_CTRL_SPLIT)
pr_info("%s: split power mode\n", pdev->name);
@@ -469,16 +480,26 @@ static u8 irqstat;
static int omap_rtc_suspend(struct device *dev)
{
+ u8 irqwake_stat;
+
irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
- /* FIXME the RTC alarm is not currently acting as a wakeup event
- * source, and in fact this enable() call is just saving a flag
- * that's never used...
+ /*
+ * FIXME. On some platforms the RTC alarm is not currently acting as a
+ * wakeup event source, and in fact this enable() call is just saving a
+ * flag that's never used...
*/
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
enable_irq_wake(omap_rtc_alarm);
- else
+
+ if (has_irq_wake_enb_bit == true) {
+ irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
+ irqwake_stat |= OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
+ rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
+ }
+ } else {
rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
+ }
/* Disable the clock/module */
pm_runtime_put_sync(dev);
@@ -488,13 +509,23 @@ static int omap_rtc_suspend(struct device *dev)
static int omap_rtc_resume(struct device *dev)
{
+ u8 irqwake_stat;
+
/* Enable the clock/module so that we can access the registers */
pm_runtime_get_sync(dev);
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
disable_irq_wake(omap_rtc_alarm);
- else
+
+ if (has_irq_wake_enb_bit == true) {
+ irqwake_stat = rtc_read(OMAP_RTC_IRQWAKEEN);
+ irqwake_stat &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN;
+ rtc_write(irqwake_stat, OMAP_RTC_IRQWAKEEN);
+ }
+ } else {
rtc_write(irqstat, OMAP_RTC_INTERRUPTS_REG);
+ }
+
return 0;
}
#endif
--
1.7.9.5
More information about the linux-arm-kernel
mailing list