aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-04-03 12:51:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-03 12:51:35 -0400
commitbad6a5c08c119572c888d5df2bd7691a4da6b9e8 (patch)
tree7070d6c17659332caad8f3d8f38b51855b3f05c4
parent03c3fa0a3bf48dcb024263a9ea41daecacbc6efa (diff)
parent0b5f037a4dc495f9c40eed7f076fc6c23af3359b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/kyle/rtc-parisc
* git://git.kernel.org/pub/scm/linux/kernel/git/kyle/rtc-parisc: powerpc/ps3: Add rtc-ps3 powerpc: Hook up rtc-generic, and kill rtc-ppc m68k: Hook up rtc-generic parisc: rtc: Rename rtc-parisc to rtc-generic parisc: rtc: Add missing module alias parisc: rtc: platform_driver_probe() fixups parisc: rtc: get_rtc_time() returns unsigned int
-rw-r--r--arch/m68k/include/asm/rtc.h7
-rw-r--r--arch/m68k/kernel/time.c18
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/kernel/time.c6
-rw-r--r--arch/powerpc/include/asm/ps3.h3
-rw-r--r--arch/powerpc/kernel/time.c16
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c2
-rw-r--r--arch/powerpc/platforms/ps3/platform.h2
-rw-r--r--arch/powerpc/platforms/ps3/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/time.c26
-rw-r--r--drivers/rtc/Kconfig31
-rw-r--r--drivers/rtc/Makefile4
-rw-r--r--drivers/rtc/rtc-generic.c84
-rw-r--r--drivers/rtc/rtc-parisc.c86
-rw-r--r--drivers/rtc/rtc-ppc.c69
-rw-r--r--drivers/rtc/rtc-ps3.c104
16 files changed, 267 insertions, 195 deletions
diff --git a/arch/m68k/include/asm/rtc.h b/arch/m68k/include/asm/rtc.h
index 5d3e03859844..a4d08ea122ee 100644
--- a/arch/m68k/include/asm/rtc.h
+++ b/arch/m68k/include/asm/rtc.h
@@ -36,13 +36,16 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
36 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated 36 * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated
37 * by the RTC when initially set to a non-zero value. 37 * by the RTC when initially set to a non-zero value.
38 */ 38 */
39 mach_hwclk(0, time); 39 if (mach_hwclk)
40 mach_hwclk(0, time);
40 return RTC_24H; 41 return RTC_24H;
41} 42}
42 43
43static inline int set_rtc_time(struct rtc_time *time) 44static inline int set_rtc_time(struct rtc_time *time)
44{ 45{
45 return mach_hwclk(1, time); 46 if (mach_hwclk)
47 return mach_hwclk(1, time);
48 return -EINVAL;
46} 49}
47 50
48static inline unsigned int get_rtc_ss(void) 51static inline unsigned int get_rtc_ss(void)
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 7db41594d7b6..54d980795fc4 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -18,6 +18,7 @@
18#include <linux/string.h> 18#include <linux/string.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/rtc.h> 20#include <linux/rtc.h>
21#include <linux/platform_device.h>
21 22
22#include <asm/machdep.h> 23#include <asm/machdep.h>
23#include <asm/io.h> 24#include <asm/io.h>
@@ -159,3 +160,20 @@ int do_settimeofday(struct timespec *tv)
159} 160}
160 161
161EXPORT_SYMBOL(do_settimeofday); 162EXPORT_SYMBOL(do_settimeofday);
163
164
165static int __init rtc_init(void)
166{
167 struct platform_device *pdev;
168
169 if (!mach_hwclk)
170 return -ENODEV;
171
172 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
173 if (IS_ERR(pdev))
174 return PTR_ERR(pdev);
175
176 return 0;
177}
178
179module_init(rtc_init);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index aacf11d33723..378b64944dc0 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -10,7 +10,7 @@ config PARISC
10 select HAVE_IDE 10 select HAVE_IDE
11 select HAVE_OPROFILE 11 select HAVE_OPROFILE
12 select RTC_CLASS 12 select RTC_CLASS
13 select RTC_DRV_PARISC 13 select RTC_DRV_GENERIC
14 select INIT_ALL_POSSIBLE 14 select INIT_ALL_POSSIBLE
15 help 15 help
16 The PA-RISC microprocessor is designed by Hewlett-Packard and used 16 The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index e75cae6072c5..86a99d02234f 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -216,14 +216,14 @@ void __init start_cpu_itimer(void)
216 per_cpu(cpu_data, cpu).it_value = next_tick; 216 per_cpu(cpu_data, cpu).it_value = next_tick;
217} 217}
218 218
219static struct platform_device rtc_parisc_dev = { 219static struct platform_device rtc_generic_dev = {
220 .name = "rtc-parisc", 220 .name = "rtc-generic",
221 .id = -1, 221 .id = -1,
222}; 222};
223 223
224static int __init rtc_init(void) 224static int __init rtc_init(void)
225{ 225{
226 if (platform_device_register(&rtc_parisc_dev) < 0) 226 if (platform_device_register(&rtc_generic_dev) < 0)
227 printk(KERN_ERR "unable to register rtc device...\n"); 227 printk(KERN_ERR "unable to register rtc device...\n");
228 228
229 /* not necessarily an error */ 229 /* not necessarily an error */
diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 67f1812698d2..cdb6fd814de8 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -50,6 +50,9 @@ enum ps3_param_av_multi_out {
50 50
51enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); 51enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
52 52
53extern u64 ps3_os_area_get_rtc_diff(void);
54extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);
55
53/* dma routines */ 56/* dma routines */
54 57
55enum ps3_dma_page_size { 58enum ps3_dma_page_size {
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c9564031a2a9..926ea864e34f 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1127,3 +1127,19 @@ void div128_by_32(u64 dividend_high, u64 dividend_low,
1127 dr->result_low = ((u64)y << 32) + z; 1127 dr->result_low = ((u64)y << 32) + z;
1128 1128
1129} 1129}
1130
1131static int __init rtc_init(void)
1132{
1133 struct platform_device *pdev;
1134
1135 if (!ppc_md.get_rtc_time)
1136 return -ENODEV;
1137
1138 pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
1139 if (IS_ERR(pdev))
1140 return PTR_ERR(pdev);
1141
1142 return 0;
1143}
1144
1145module_init(rtc_init);
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
index e1c83c23b435..86e392b1b049 100644
--- a/arch/powerpc/platforms/ps3/os-area.c
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -808,6 +808,7 @@ u64 ps3_os_area_get_rtc_diff(void)
808{ 808{
809 return saved_params.rtc_diff; 809 return saved_params.rtc_diff;
810} 810}
811EXPORT_SYMBOL(ps3_os_area_get_rtc_diff);
811 812
812/** 813/**
813 * ps3_os_area_set_rtc_diff - Set the rtc diff value. 814 * ps3_os_area_set_rtc_diff - Set the rtc diff value.
@@ -823,6 +824,7 @@ void ps3_os_area_set_rtc_diff(u64 rtc_diff)
823 os_area_queue_work(); 824 os_area_queue_work();
824 } 825 }
825} 826}
827EXPORT_SYMBOL(ps3_os_area_set_rtc_diff);
826 828
827/** 829/**
828 * ps3_os_area_get_av_multi_out - Returns the default video mode. 830 * ps3_os_area_get_av_multi_out - Returns the default video mode.
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 235c13ebacd9..136aa0637d9c 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -64,8 +64,6 @@ int ps3_set_rtc_time(struct rtc_time *time);
64 64
65void __init ps3_os_area_save_params(void); 65void __init ps3_os_area_save_params(void);
66void __init ps3_os_area_init(void); 66void __init ps3_os_area_init(void);
67u64 ps3_os_area_get_rtc_diff(void);
68void ps3_os_area_set_rtc_diff(u64 rtc_diff);
69 67
70/* spu */ 68/* spu */
71 69
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 3331ccbb8d38..66181821322a 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -270,8 +270,6 @@ define_machine(ps3) {
270 .init_IRQ = ps3_init_IRQ, 270 .init_IRQ = ps3_init_IRQ,
271 .panic = ps3_panic, 271 .panic = ps3_panic,
272 .get_boot_time = ps3_get_boot_time, 272 .get_boot_time = ps3_get_boot_time,
273 .set_rtc_time = ps3_set_rtc_time,
274 .get_rtc_time = ps3_get_rtc_time,
275 .set_dabr = ps3_set_dabr, 273 .set_dabr = ps3_set_dabr,
276 .calibrate_decr = ps3_calibrate_decr, 274 .calibrate_decr = ps3_calibrate_decr,
277 .progress = ps3_progress, 275 .progress = ps3_progress,
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
index d0daf7d6d3b2..b178a1e66c91 100644
--- a/arch/powerpc/platforms/ps3/time.c
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/platform_device.h>
22 23
23#include <asm/rtc.h> 24#include <asm/rtc.h>
24#include <asm/lv1call.h> 25#include <asm/lv1call.h>
@@ -74,23 +75,20 @@ static u64 read_rtc(void)
74 return rtc_val; 75 return rtc_val;
75} 76}
76 77
77int ps3_set_rtc_time(struct rtc_time *tm) 78unsigned long __init ps3_get_boot_time(void)
78{ 79{
79 u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 80 return read_rtc() + ps3_os_area_get_rtc_diff();
80 tm->tm_hour, tm->tm_min, tm->tm_sec);
81
82 ps3_os_area_set_rtc_diff(now - read_rtc());
83 return 0;
84} 81}
85 82
86void ps3_get_rtc_time(struct rtc_time *tm) 83static int __init ps3_rtc_init(void)
87{ 84{
88 to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm); 85 struct platform_device *pdev;
89 tm->tm_year -= 1900;
90 tm->tm_mon -= 1;
91}
92 86
93unsigned long __init ps3_get_boot_time(void) 87 pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
94{ 88 if (IS_ERR(pdev))
95 return read_rtc() + ps3_os_area_get_rtc_diff(); 89 return PTR_ERR(pdev);
90
91 return 0;
96} 92}
93
94module_init(ps3_rtc_init);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 56002f7d26bd..ffe34a12f446 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -688,22 +688,16 @@ config RTC_DRV_RS5C313
688 help 688 help
689 If you say yes here you get support for the Ricoh RS5C313 RTC chips. 689 If you say yes here you get support for the Ricoh RS5C313 RTC chips.
690 690
691config RTC_DRV_PARISC 691config RTC_DRV_GENERIC
692 tristate "PA-RISC firmware RTC support" 692 tristate "Generic RTC support"
693 depends on PARISC 693 # Please consider writing a new RTC driver instead of using the generic
694 help 694 # RTC abstraction
695 Say Y or M here to enable RTC support on PA-RISC systems using 695 depends on PARISC || M68K || PPC
696 firmware calls. If you do not know what you are doing, you should 696 help
697 Say Y or M here to enable RTC support on systems using the generic
698 RTC abstraction. If you do not know what you are doing, you should
697 just say Y. 699 just say Y.
698 700
699config RTC_DRV_PPC
700 tristate "PowerPC machine dependent RTC support"
701 depends on PPC
702 help
703 The PowerPC kernel has machine-specific functions for accessing
704 the RTC. This exposes that functionality through the generic RTC
705 class.
706
707config RTC_DRV_PXA 701config RTC_DRV_PXA
708 tristate "PXA27x/PXA3xx" 702 tristate "PXA27x/PXA3xx"
709 depends on ARCH_PXA 703 depends on ARCH_PXA
@@ -747,4 +741,13 @@ config RTC_DRV_MV
747 This driver can also be built as a module. If so, the module 741 This driver can also be built as a module. If so, the module
748 will be called rtc-mv. 742 will be called rtc-mv.
749 743
744config RTC_DRV_PS3
745 tristate "PS3 RTC"
746 depends on PPC_PS3
747 help
748 If you say yes here you will get support for the RTC on PS3.
749
750 This driver can also be built as a module. If so, the module
751 will be called rtc-ps3.
752
750endif # RTC_CLASS 753endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index e7b09986d26e..6c0639a14f09 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -56,8 +56,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
56obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o 56obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
57obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o 57obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
58obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o 58obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
59obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o 59obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
60obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
61obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o 60obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
62obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o 61obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
63obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o 62obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
@@ -77,3 +76,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
77obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o 76obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
78obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o 77obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
79obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o 78obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
79obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
new file mode 100644
index 000000000000..98322004ad2e
--- /dev/null
+++ b/drivers/rtc/rtc-generic.c
@@ -0,0 +1,84 @@
1/* rtc-generic: RTC driver using the generic RTC abstraction
2 *
3 * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/time.h>
9#include <linux/platform_device.h>
10#include <linux/rtc.h>
11
12#include <asm/rtc.h>
13
14static int generic_get_time(struct device *dev, struct rtc_time *tm)
15{
16 unsigned int ret = get_rtc_time(tm);
17
18 if (ret & RTC_BATT_BAD)
19 return -EOPNOTSUPP;
20
21 return rtc_valid_tm(tm);
22}
23
24static int generic_set_time(struct device *dev, struct rtc_time *tm)
25{
26 if (set_rtc_time(tm) < 0)
27 return -EOPNOTSUPP;
28
29 return 0;
30}
31
32static const struct rtc_class_ops generic_rtc_ops = {
33 .read_time = generic_get_time,
34 .set_time = generic_set_time,
35};
36
37static int __init generic_rtc_probe(struct platform_device *dev)
38{
39 struct rtc_device *rtc;
40
41 rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
42 THIS_MODULE);
43 if (IS_ERR(rtc))
44 return PTR_ERR(rtc);
45
46 platform_set_drvdata(dev, rtc);
47
48 return 0;
49}
50
51static int __exit generic_rtc_remove(struct platform_device *dev)
52{
53 struct rtc_device *rtc = platform_get_drvdata(dev);
54
55 rtc_device_unregister(rtc);
56
57 return 0;
58}
59
60static struct platform_driver generic_rtc_driver = {
61 .driver = {
62 .name = "rtc-generic",
63 .owner = THIS_MODULE,
64 },
65 .remove = __exit_p(generic_rtc_remove),
66};
67
68static int __init generic_rtc_init(void)
69{
70 return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
71}
72
73static void __exit generic_rtc_fini(void)
74{
75 platform_driver_unregister(&generic_rtc_driver);
76}
77
78module_init(generic_rtc_init);
79module_exit(generic_rtc_fini);
80
81MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
82MODULE_LICENSE("GPL");
83MODULE_DESCRIPTION("Generic RTC driver");
84MODULE_ALIAS("platform:rtc-generic");
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
deleted file mode 100644
index b966f56da976..000000000000
--- a/drivers/rtc/rtc-parisc.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/* rtc-parisc: RTC for HP PA-RISC firmware
2 *
3 * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/time.h>
9#include <linux/platform_device.h>
10#include <linux/rtc.h>
11
12#include <asm/rtc.h>
13
14static int parisc_get_time(struct device *dev, struct rtc_time *tm)
15{
16 unsigned long ret;
17
18 ret = get_rtc_time(tm);
19
20 if (ret & RTC_BATT_BAD)
21 return -EOPNOTSUPP;
22
23 return rtc_valid_tm(tm);
24}
25
26static int parisc_set_time(struct device *dev, struct rtc_time *tm)
27{
28 if (set_rtc_time(tm) < 0)
29 return -EOPNOTSUPP;
30
31 return 0;
32}
33
34static const struct rtc_class_ops parisc_rtc_ops = {
35 .read_time = parisc_get_time,
36 .set_time = parisc_set_time,
37};
38
39static int __init parisc_rtc_probe(struct platform_device *dev)
40{
41 struct rtc_device *rtc;
42
43 rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
44 THIS_MODULE);
45 if (IS_ERR(rtc))
46 return PTR_ERR(rtc);
47
48 platform_set_drvdata(dev, rtc);
49
50 return 0;
51}
52
53static int __exit parisc_rtc_remove(struct platform_device *dev)
54{
55 struct rtc_device *rtc = platform_get_drvdata(dev);
56
57 rtc_device_unregister(rtc);
58
59 return 0;
60}
61
62static struct platform_driver parisc_rtc_driver = {
63 .driver = {
64 .name = "rtc-parisc",
65 .owner = THIS_MODULE,
66 },
67 .probe = parisc_rtc_probe,
68 .remove = __devexit_p(parisc_rtc_remove),
69};
70
71static int __init parisc_rtc_init(void)
72{
73 return platform_driver_probe(&parisc_rtc_driver, parisc_rtc_probe);
74}
75
76static void __exit parisc_rtc_fini(void)
77{
78 platform_driver_unregister(&parisc_rtc_driver);
79}
80
81module_init(parisc_rtc_init);
82module_exit(parisc_rtc_fini);
83
84MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
85MODULE_LICENSE("GPL");
86MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c
deleted file mode 100644
index c8e97e25ef7e..000000000000
--- a/drivers/rtc/rtc-ppc.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * RTC driver for ppc_md RTC functions
3 *
4 * © 2007 Red Hat, Inc.
5 *
6 * Author: David Woodhouse <dwmw2@infradead.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13
14#include <linux/module.h>
15#include <linux/err.h>
16#include <linux/rtc.h>
17#include <linux/platform_device.h>
18#include <asm/machdep.h>
19
20static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
21{
22 ppc_md.get_rtc_time(tm);
23 return 0;
24}
25
26static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
27{
28 return ppc_md.set_rtc_time(tm);
29}
30
31static const struct rtc_class_ops ppc_rtc_ops = {
32 .set_time = ppc_rtc_set_time,
33 .read_time = ppc_rtc_read_time,
34};
35
36static struct rtc_device *rtc;
37static struct platform_device *ppc_rtc_pdev;
38
39static int __init ppc_rtc_init(void)
40{
41 if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
42 return -ENODEV;
43
44 ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
45 if (IS_ERR(ppc_rtc_pdev))
46 return PTR_ERR(ppc_rtc_pdev);
47
48 rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
49 &ppc_rtc_ops, THIS_MODULE);
50 if (IS_ERR(rtc)) {
51 platform_device_unregister(ppc_rtc_pdev);
52 return PTR_ERR(rtc);
53 }
54
55 return 0;
56}
57
58static void __exit ppc_rtc_exit(void)
59{
60 rtc_device_unregister(rtc);
61 platform_device_unregister(ppc_rtc_pdev);
62}
63
64module_init(ppc_rtc_init);
65module_exit(ppc_rtc_exit);
66
67MODULE_LICENSE("GPL");
68MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
69MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
new file mode 100644
index 000000000000..968133ce1ee8
--- /dev/null
+++ b/drivers/rtc/rtc-ps3.c
@@ -0,0 +1,104 @@
1/*
2 * PS3 RTC Driver
3 *
4 * Copyright 2009 Sony Corporation
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; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.
17 * If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/rtc.h>
24
25#include <asm/lv1call.h>
26#include <asm/ps3.h>
27
28
29static u64 read_rtc(void)
30{
31 int result;
32 u64 rtc_val;
33 u64 tb_val;
34
35 result = lv1_get_rtc(&rtc_val, &tb_val);
36 BUG_ON(result);
37
38 return rtc_val;
39}
40
41static int ps3_get_time(struct device *dev, struct rtc_time *tm)
42{
43 rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
44 return rtc_valid_tm(tm);
45}
46
47static int ps3_set_time(struct device *dev, struct rtc_time *tm)
48{
49 unsigned long now;
50
51 rtc_tm_to_time(tm, &now);
52 ps3_os_area_set_rtc_diff(now - read_rtc());
53 return 0;
54}
55
56static const struct rtc_class_ops ps3_rtc_ops = {
57 .read_time = ps3_get_time,
58 .set_time = ps3_set_time,
59};
60
61static int __init ps3_rtc_probe(struct platform_device *dev)
62{
63 struct rtc_device *rtc;
64
65 rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
66 THIS_MODULE);
67 if (IS_ERR(rtc))
68 return PTR_ERR(rtc);
69
70 platform_set_drvdata(dev, rtc);
71 return 0;
72}
73
74static int __exit ps3_rtc_remove(struct platform_device *dev)
75{
76 rtc_device_unregister(platform_get_drvdata(dev));
77 return 0;
78}
79
80static struct platform_driver ps3_rtc_driver = {
81 .driver = {
82 .name = "rtc-ps3",
83 .owner = THIS_MODULE,
84 },
85 .remove = __exit_p(ps3_rtc_remove),
86};
87
88static int __init ps3_rtc_init(void)
89{
90 return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
91}
92
93static void __exit ps3_rtc_fini(void)
94{
95 platform_driver_unregister(&ps3_rtc_driver);
96}
97
98module_init(ps3_rtc_init);
99module_exit(ps3_rtc_fini);
100
101MODULE_AUTHOR("Sony Corporation");
102MODULE_LICENSE("GPL");
103MODULE_DESCRIPTION("ps3 RTC driver");
104MODULE_ALIAS("platform:rtc-ps3");