1 /* 2 * Support for OLPC XO-1 Real Time Clock (RTC) 3 * 4 * Copyright (C) 2011 One Laptop per Child 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <linux/mc146818rtc.h> 13 #include <linux/platform_device.h> 14 #include <linux/rtc.h> 15 #include <linux/of.h> 16 17 #include <asm/msr.h> 18 #include <asm/olpc.h> 19 20 static void rtc_wake_on(struct device *dev) 21 { 22 olpc_xo1_pm_wakeup_set(CS5536_PM_RTC); 23 } 24 25 static void rtc_wake_off(struct device *dev) 26 { 27 olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC); 28 } 29 30 static struct resource rtc_platform_resource[] = { 31 [0] = { 32 .start = RTC_PORT(0), 33 .end = RTC_PORT(1), 34 .flags = IORESOURCE_IO, 35 }, 36 [1] = { 37 .start = RTC_IRQ, 38 .end = RTC_IRQ, 39 .flags = IORESOURCE_IRQ, 40 } 41 }; 42 43 static struct cmos_rtc_board_info rtc_info = { 44 .rtc_day_alarm = 0, 45 .rtc_mon_alarm = 0, 46 .rtc_century = 0, 47 .wake_on = rtc_wake_on, 48 .wake_off = rtc_wake_off, 49 }; 50 51 static struct platform_device xo1_rtc_device = { 52 .name = "rtc_cmos", 53 .id = -1, 54 .num_resources = ARRAY_SIZE(rtc_platform_resource), 55 .dev.platform_data = &rtc_info, 56 .resource = rtc_platform_resource, 57 }; 58 59 static int __init xo1_rtc_init(void) 60 { 61 int r; 62 struct device_node *node; 63 64 node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc"); 65 if (!node) 66 return 0; 67 of_node_put(node); 68 69 pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n"); 70 rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm); 71 rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm); 72 rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century); 73 74 r = platform_device_register(&xo1_rtc_device); 75 if (r) 76 return r; 77 78 device_init_wakeup(&xo1_rtc_device.dev, 1); 79 return 0; 80 } 81 arch_initcall(xo1_rtc_init); 82