diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2011-05-09 13:28:43 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2011-05-17 14:44:36 -0400 |
commit | dd196a2b3dbd192ff3ccf263d12b59bf22572958 (patch) | |
tree | c2639777ee4022a67ca562242c1edd82a4a10466 | |
parent | 18aecc2b645bbb07851b196452a2af314222069b (diff) |
tile: add an RTC driver for the Tilera hypervisor
This is a simple RTC driver that lets Tilera hardware boot up and
set the clock correctly.
Acked-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r-- | arch/tile/configs/tile_defconfig | 1 | ||||
-rw-r--r-- | arch/tile/configs/tilegx_defconfig | 63 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 7 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-tile.c | 162 |
5 files changed, 231 insertions, 3 deletions
diff --git a/arch/tile/configs/tile_defconfig b/arch/tile/configs/tile_defconfig index cb47612f77a7..f58dc362b944 100644 --- a/arch/tile/configs/tile_defconfig +++ b/arch/tile/configs/tile_defconfig | |||
@@ -796,6 +796,7 @@ CONFIG_RTC_INTF_DEV=y | |||
796 | # | 796 | # |
797 | # on-CPU RTC drivers | 797 | # on-CPU RTC drivers |
798 | # | 798 | # |
799 | CONFIG_RTC_DRV_TILE=y | ||
799 | # CONFIG_DMADEVICES is not set | 800 | # CONFIG_DMADEVICES is not set |
800 | # CONFIG_AUXDISPLAY is not set | 801 | # CONFIG_AUXDISPLAY is not set |
801 | # CONFIG_UIO is not set | 802 | # CONFIG_UIO is not set |
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 776ec0c5cba8..09f1c7fad8bf 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig | |||
@@ -1135,8 +1135,6 @@ CONFIG_HVC_DRIVER=y | |||
1135 | # CONFIG_IPMI_HANDLER is not set | 1135 | # CONFIG_IPMI_HANDLER is not set |
1136 | CONFIG_HW_RANDOM=y | 1136 | CONFIG_HW_RANDOM=y |
1137 | CONFIG_HW_RANDOM_TIMERIOMEM=m | 1137 | CONFIG_HW_RANDOM_TIMERIOMEM=m |
1138 | # CONFIG_RTC is not set | ||
1139 | # CONFIG_GEN_RTC is not set | ||
1140 | # CONFIG_R3964 is not set | 1138 | # CONFIG_R3964 is not set |
1141 | # CONFIG_APPLICOM is not set | 1139 | # CONFIG_APPLICOM is not set |
1142 | 1140 | ||
@@ -1277,7 +1275,66 @@ CONFIG_MFD_SUPPORT=y | |||
1277 | # CONFIG_ACCESSIBILITY is not set | 1275 | # CONFIG_ACCESSIBILITY is not set |
1278 | # CONFIG_INFINIBAND is not set | 1276 | # CONFIG_INFINIBAND is not set |
1279 | # CONFIG_EDAC is not set | 1277 | # CONFIG_EDAC is not set |
1280 | # CONFIG_RTC_CLASS is not set | 1278 | CONFIG_RTC_LIB=y |
1279 | CONFIG_RTC_CLASS=y | ||
1280 | CONFIG_RTC_HCTOSYS=y | ||
1281 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
1282 | # CONFIG_RTC_DEBUG is not set | ||
1283 | |||
1284 | # | ||
1285 | # RTC interfaces | ||
1286 | # | ||
1287 | CONFIG_RTC_INTF_SYSFS=y | ||
1288 | CONFIG_RTC_INTF_PROC=y | ||
1289 | CONFIG_RTC_INTF_DEV=y | ||
1290 | # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set | ||
1291 | # CONFIG_RTC_DRV_TEST is not set | ||
1292 | |||
1293 | # | ||
1294 | # I2C RTC drivers | ||
1295 | # | ||
1296 | # CONFIG_RTC_DRV_DS1307 is not set | ||
1297 | # CONFIG_RTC_DRV_DS1374 is not set | ||
1298 | # CONFIG_RTC_DRV_DS1672 is not set | ||
1299 | # CONFIG_RTC_DRV_DS3232 is not set | ||
1300 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
1301 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
1302 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
1303 | # CONFIG_RTC_DRV_ISL12022 is not set | ||
1304 | # CONFIG_RTC_DRV_X1205 is not set | ||
1305 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
1306 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
1307 | # CONFIG_RTC_DRV_M41T80 is not set | ||
1308 | # CONFIG_RTC_DRV_BQ32K is not set | ||
1309 | # CONFIG_RTC_DRV_S35390A is not set | ||
1310 | # CONFIG_RTC_DRV_FM3130 is not set | ||
1311 | # CONFIG_RTC_DRV_RX8581 is not set | ||
1312 | # CONFIG_RTC_DRV_RX8025 is not set | ||
1313 | |||
1314 | # | ||
1315 | # SPI RTC drivers | ||
1316 | # | ||
1317 | |||
1318 | # | ||
1319 | # Platform RTC drivers | ||
1320 | # | ||
1321 | # CONFIG_RTC_DRV_DS1286 is not set | ||
1322 | # CONFIG_RTC_DRV_DS1511 is not set | ||
1323 | # CONFIG_RTC_DRV_DS1553 is not set | ||
1324 | # CONFIG_RTC_DRV_DS1742 is not set | ||
1325 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
1326 | # CONFIG_RTC_DRV_M48T86 is not set | ||
1327 | # CONFIG_RTC_DRV_M48T35 is not set | ||
1328 | # CONFIG_RTC_DRV_M48T59 is not set | ||
1329 | # CONFIG_RTC_DRV_MSM6242 is not set | ||
1330 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
1331 | # CONFIG_RTC_DRV_RP5C01 is not set | ||
1332 | # CONFIG_RTC_DRV_V3020 is not set | ||
1333 | |||
1334 | # | ||
1335 | # on-CPU RTC drivers | ||
1336 | # | ||
1337 | CONFIG_RTC_DRV_TILE=y | ||
1281 | # CONFIG_DMADEVICES is not set | 1338 | # CONFIG_DMADEVICES is not set |
1282 | # CONFIG_AUXDISPLAY is not set | 1339 | # CONFIG_AUXDISPLAY is not set |
1283 | # CONFIG_UIO is not set | 1340 | # CONFIG_UIO is not set |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index e1878877399c..d2c615fcaa10 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -995,4 +995,11 @@ config RTC_DRV_TEGRA | |||
995 | This drive can also be built as a module. If so, the module | 995 | This drive can also be built as a module. If so, the module |
996 | will be called rtc-tegra. | 996 | will be called rtc-tegra. |
997 | 997 | ||
998 | config RTC_DRV_TILE | ||
999 | tristate "Tilera hypervisor RTC support" | ||
1000 | depends on TILE | ||
1001 | help | ||
1002 | Enable support for the Linux driver side of the Tilera | ||
1003 | hypervisor's real-time clock interface. | ||
1004 | |||
998 | endif # RTC_CLASS | 1005 | endif # RTC_CLASS |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ca91c3c42e98..9574748d1c73 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -93,6 +93,7 @@ obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o | |||
93 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o | 93 | obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o |
94 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o | 94 | obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o |
95 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | 95 | obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o |
96 | obj-$(CONFIG_RTC_DRV_TILE) += rtc-tile.o | ||
96 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o | 97 | obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o |
97 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o | 98 | obj-$(CONFIG_RTC_DRV_TX4939) += rtc-tx4939.o |
98 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 99 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c new file mode 100644 index 000000000000..eb65dafee66e --- /dev/null +++ b/drivers/rtc/rtc-tile.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Tilera Corporation. All Rights Reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation, version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
11 | * NON INFRINGEMENT. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * Tilera-specific RTC driver. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/rtc.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | /* Platform device pointer. */ | ||
23 | static struct platform_device *tile_rtc_platform_device; | ||
24 | |||
25 | /* | ||
26 | * RTC read routine. Gets time info from RTC chip via hypervisor syscall. | ||
27 | */ | ||
28 | static int read_rtc_time(struct device *dev, struct rtc_time *tm) | ||
29 | { | ||
30 | HV_RTCTime hvtm = hv_get_rtc(); | ||
31 | |||
32 | tm->tm_sec = hvtm.tm_sec; | ||
33 | tm->tm_min = hvtm.tm_min; | ||
34 | tm->tm_hour = hvtm.tm_hour; | ||
35 | tm->tm_mday = hvtm.tm_mday; | ||
36 | tm->tm_mon = hvtm.tm_mon; | ||
37 | tm->tm_year = hvtm.tm_year; | ||
38 | tm->tm_wday = 0; | ||
39 | tm->tm_yday = 0; | ||
40 | tm->tm_isdst = 0; | ||
41 | |||
42 | if (rtc_valid_tm(tm) < 0) | ||
43 | dev_warn(dev, "Read invalid date/time from RTC\n"); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | /* | ||
49 | * RTC write routine. Sends time info to hypervisor via syscall, to be | ||
50 | * written to RTC chip. | ||
51 | */ | ||
52 | static int set_rtc_time(struct device *dev, struct rtc_time *tm) | ||
53 | { | ||
54 | HV_RTCTime hvtm; | ||
55 | |||
56 | hvtm.tm_sec = tm->tm_sec; | ||
57 | hvtm.tm_min = tm->tm_min; | ||
58 | hvtm.tm_hour = tm->tm_hour; | ||
59 | hvtm.tm_mday = tm->tm_mday; | ||
60 | hvtm.tm_mon = tm->tm_mon; | ||
61 | hvtm.tm_year = tm->tm_year; | ||
62 | |||
63 | hv_set_rtc(hvtm); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * RTC read/write ops. | ||
70 | */ | ||
71 | static const struct rtc_class_ops tile_rtc_ops = { | ||
72 | .read_time = read_rtc_time, | ||
73 | .set_time = set_rtc_time, | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * Device probe routine. | ||
78 | */ | ||
79 | static int __devinit tile_rtc_probe(struct platform_device *dev) | ||
80 | { | ||
81 | struct rtc_device *rtc; | ||
82 | |||
83 | rtc = rtc_device_register("tile", | ||
84 | &dev->dev, &tile_rtc_ops, THIS_MODULE); | ||
85 | |||
86 | if (IS_ERR(rtc)) | ||
87 | return PTR_ERR(rtc); | ||
88 | |||
89 | platform_set_drvdata(dev, rtc); | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * Device cleanup routine. | ||
96 | */ | ||
97 | static int __devexit tile_rtc_remove(struct platform_device *dev) | ||
98 | { | ||
99 | struct rtc_device *rtc = platform_get_drvdata(dev); | ||
100 | |||
101 | if (rtc) | ||
102 | rtc_device_unregister(rtc); | ||
103 | |||
104 | platform_set_drvdata(dev, NULL); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static struct platform_driver tile_rtc_platform_driver = { | ||
110 | .driver = { | ||
111 | .name = "rtc-tile", | ||
112 | .owner = THIS_MODULE, | ||
113 | }, | ||
114 | .probe = tile_rtc_probe, | ||
115 | .remove = __devexit_p(tile_rtc_remove), | ||
116 | }; | ||
117 | |||
118 | /* | ||
119 | * Driver init routine. | ||
120 | */ | ||
121 | static int __init tile_rtc_driver_init(void) | ||
122 | { | ||
123 | int err; | ||
124 | |||
125 | err = platform_driver_register(&tile_rtc_platform_driver); | ||
126 | if (err) | ||
127 | return err; | ||
128 | |||
129 | tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0); | ||
130 | if (tile_rtc_platform_device == NULL) { | ||
131 | err = -ENOMEM; | ||
132 | goto exit_driver_unregister; | ||
133 | } | ||
134 | |||
135 | err = platform_device_add(tile_rtc_platform_device); | ||
136 | if (err) | ||
137 | goto exit_device_put; | ||
138 | |||
139 | return 0; | ||
140 | |||
141 | exit_device_put: | ||
142 | platform_device_put(tile_rtc_platform_device); | ||
143 | |||
144 | exit_driver_unregister: | ||
145 | platform_driver_unregister(&tile_rtc_platform_driver); | ||
146 | return err; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Driver cleanup routine. | ||
151 | */ | ||
152 | static void __exit tile_rtc_driver_exit(void) | ||
153 | { | ||
154 | platform_driver_unregister(&tile_rtc_platform_driver); | ||
155 | } | ||
156 | |||
157 | module_init(tile_rtc_driver_init); | ||
158 | module_exit(tile_rtc_driver_exit); | ||
159 | |||
160 | MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver"); | ||
161 | MODULE_LICENSE("GPL"); | ||
162 | MODULE_ALIAS("platform:rtc-tile"); | ||