|
@@ -0,0 +1,81 @@
|
|
|
+/*
|
|
|
+ * Support for OLPC XO-1 Real Time Clock (RTC)
|
|
|
+ *
|
|
|
+ * Copyright (C) 2011 One Laptop per Child
|
|
|
+ *
|
|
|
+ * 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
|
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
|
+ * (at your option) any later version.
|
|
|
+ */
|
|
|
+
|
|
|
+#include <linux/mc146818rtc.h>
|
|
|
+#include <linux/platform_device.h>
|
|
|
+#include <linux/rtc.h>
|
|
|
+#include <linux/of.h>
|
|
|
+
|
|
|
+#include <asm/msr.h>
|
|
|
+#include <asm/olpc.h>
|
|
|
+
|
|
|
+static void rtc_wake_on(struct device *dev)
|
|
|
+{
|
|
|
+ olpc_xo1_pm_wakeup_set(CS5536_PM_RTC);
|
|
|
+}
|
|
|
+
|
|
|
+static void rtc_wake_off(struct device *dev)
|
|
|
+{
|
|
|
+ olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC);
|
|
|
+}
|
|
|
+
|
|
|
+static struct resource rtc_platform_resource[] = {
|
|
|
+ [0] = {
|
|
|
+ .start = RTC_PORT(0),
|
|
|
+ .end = RTC_PORT(1),
|
|
|
+ .flags = IORESOURCE_IO,
|
|
|
+ },
|
|
|
+ [1] = {
|
|
|
+ .start = RTC_IRQ,
|
|
|
+ .end = RTC_IRQ,
|
|
|
+ .flags = IORESOURCE_IRQ,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+static struct cmos_rtc_board_info rtc_info = {
|
|
|
+ .rtc_day_alarm = 0,
|
|
|
+ .rtc_mon_alarm = 0,
|
|
|
+ .rtc_century = 0,
|
|
|
+ .wake_on = rtc_wake_on,
|
|
|
+ .wake_off = rtc_wake_off,
|
|
|
+};
|
|
|
+
|
|
|
+static struct platform_device xo1_rtc_device = {
|
|
|
+ .name = "rtc_cmos",
|
|
|
+ .id = -1,
|
|
|
+ .num_resources = ARRAY_SIZE(rtc_platform_resource),
|
|
|
+ .dev.platform_data = &rtc_info,
|
|
|
+ .resource = rtc_platform_resource,
|
|
|
+};
|
|
|
+
|
|
|
+static int __init xo1_rtc_init(void)
|
|
|
+{
|
|
|
+ int r;
|
|
|
+ struct device_node *node;
|
|
|
+
|
|
|
+ node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc");
|
|
|
+ if (!node)
|
|
|
+ return 0;
|
|
|
+ of_node_put(node);
|
|
|
+
|
|
|
+ pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n");
|
|
|
+ rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm);
|
|
|
+ rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm);
|
|
|
+ rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century);
|
|
|
+
|
|
|
+ r = platform_device_register(&xo1_rtc_device);
|
|
|
+ if (r)
|
|
|
+ return r;
|
|
|
+
|
|
|
+ device_init_wakeup(&xo1_rtc_device.dev, 1);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+arch_initcall(xo1_rtc_init);
|