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