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 #include <asm/x86_init.h> 20 21 static void rtc_wake_on(struct device *dev) 22 { 23 olpc_xo1_pm_wakeup_set(CS5536_PM_RTC); 24 } 25 26 static void rtc_wake_off(struct device *dev) 27 { 28 olpc_xo1_pm_wakeup_clear(CS5536_PM_RTC); 29 } 30 31 static struct resource rtc_platform_resource[] = { 32 [0] = { 33 .start = RTC_PORT(0), 34 .end = RTC_PORT(1), 35 .flags = IORESOURCE_IO, 36 }, 37 [1] = { 38 .start = RTC_IRQ, 39 .end = RTC_IRQ, 40 .flags = IORESOURCE_IRQ, 41 } 42 }; 43 44 static struct cmos_rtc_board_info rtc_info = { 45 .rtc_day_alarm = 0, 46 .rtc_mon_alarm = 0, 47 .rtc_century = 0, 48 .wake_on = rtc_wake_on, 49 .wake_off = rtc_wake_off, 50 }; 51 52 static struct platform_device xo1_rtc_device = { 53 .name = "rtc_cmos", 54 .id = -1, 55 .num_resources = ARRAY_SIZE(rtc_platform_resource), 56 .dev.platform_data = &rtc_info, 57 .resource = rtc_platform_resource, 58 }; 59 60 static int __init xo1_rtc_init(void) 61 { 62 int r; 63 struct device_node *node; 64 65 node = of_find_compatible_node(NULL, NULL, "olpc,xo1-rtc"); 66 if (!node) 67 return 0; 68 of_node_put(node); 69 70 pr_info("olpc-xo1-rtc: Initializing OLPC XO-1 RTC\n"); 71 rdmsrl(MSR_RTC_DOMA_OFFSET, rtc_info.rtc_day_alarm); 72 rdmsrl(MSR_RTC_MONA_OFFSET, rtc_info.rtc_mon_alarm); 73 rdmsrl(MSR_RTC_CEN_OFFSET, rtc_info.rtc_century); 74 75 r = platform_device_register(&xo1_rtc_device); 76 if (r) 77 return r; 78 79 x86_platform.legacy.rtc = 0; 80 81 device_init_wakeup(&xo1_rtc_device.dev, 1); 82 return 0; 83 } 84 arch_initcall(xo1_rtc_init); 85