diff options
-rw-r--r-- | arch/parisc/Kconfig | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/time.c | 20 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-parisc.c | 111 |
5 files changed, 141 insertions, 1 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index a7d4fd353c2b..0a8ac703dbec 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -9,6 +9,8 @@ config PARISC | |||
9 | def_bool y | 9 | def_bool y |
10 | select HAVE_IDE | 10 | select HAVE_IDE |
11 | select HAVE_OPROFILE | 11 | select HAVE_OPROFILE |
12 | select RTC_CLASS | ||
13 | select RTC_DRV_PARISC | ||
12 | help | 14 | help |
13 | The PA-RISC microprocessor is designed by Hewlett-Packard and used | 15 | The PA-RISC microprocessor is designed by Hewlett-Packard and used |
14 | in many of their workstations & servers (HP9000 700 and 800 series, | 16 | in many of their workstations & servers (HP9000 700 and 800 series, |
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index 24be86bba94d..4d09203bc693 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
24 | #include <linux/profile.h> | 24 | #include <linux/profile.h> |
25 | #include <linux/clocksource.h> | 25 | #include <linux/clocksource.h> |
26 | #include <linux/platform_device.h> | ||
26 | 27 | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | #include <asm/io.h> | 29 | #include <asm/io.h> |
@@ -215,6 +216,24 @@ void __init start_cpu_itimer(void) | |||
215 | cpu_data[cpu].it_value = next_tick; | 216 | cpu_data[cpu].it_value = next_tick; |
216 | } | 217 | } |
217 | 218 | ||
219 | struct platform_device rtc_parisc_dev = { | ||
220 | .name = "rtc-parisc", | ||
221 | .id = -1, | ||
222 | }; | ||
223 | |||
224 | static int __init rtc_init(void) | ||
225 | { | ||
226 | int ret; | ||
227 | |||
228 | ret = platform_device_register(&rtc_parisc_dev); | ||
229 | if (ret < 0) | ||
230 | printk(KERN_ERR "unable to register rtc device...\n"); | ||
231 | |||
232 | /* not necessarily an error */ | ||
233 | return 0; | ||
234 | } | ||
235 | module_init(rtc_init); | ||
236 | |||
218 | void __init time_init(void) | 237 | void __init time_init(void) |
219 | { | 238 | { |
220 | static struct pdc_tod tod_data; | 239 | static struct pdc_tod tod_data; |
@@ -245,4 +264,3 @@ void __init time_init(void) | |||
245 | xtime.tv_nsec = 0; | 264 | xtime.tv_nsec = 0; |
246 | } | 265 | } |
247 | } | 266 | } |
248 | |||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9a9755c92fad..30d40fe194a8 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -575,6 +575,14 @@ config RTC_DRV_RS5C313 | |||
575 | help | 575 | help |
576 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. | 576 | If you say yes here you get support for the Ricoh RS5C313 RTC chips. |
577 | 577 | ||
578 | config RTC_DRV_PARISC | ||
579 | tristate "PA-RISC firmware RTC support" | ||
580 | depends on PARISC | ||
581 | help | ||
582 | Say Y or M here to enable RTC support on PA-RISC systems using | ||
583 | firmware calls. If you do not know what you are doing, you should | ||
584 | just say Y. | ||
585 | |||
578 | config RTC_DRV_PPC | 586 | config RTC_DRV_PPC |
579 | tristate "PowerPC machine dependent RTC support" | 587 | tristate "PowerPC machine dependent RTC support" |
580 | depends on PPC_MERGE | 588 | depends on PPC_MERGE |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 18622ef84cab..180ddacde730 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | |||
45 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 45 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
46 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o | 46 | obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o |
47 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 47 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
48 | obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o | ||
48 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | 49 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o |
49 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 50 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
50 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 51 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c new file mode 100644 index 000000000000..346d633655e7 --- /dev/null +++ b/drivers/rtc/rtc-parisc.c | |||
@@ -0,0 +1,111 @@ | |||
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 | |||
11 | #include <asm/rtc.h> | ||
12 | |||
13 | /* as simple as can be, and no simpler. */ | ||
14 | struct parisc_rtc { | ||
15 | struct rtc_device *rtc; | ||
16 | spinlock_t lock; | ||
17 | }; | ||
18 | |||
19 | static int parisc_get_time(struct device *dev, struct rtc_time *tm) | ||
20 | { | ||
21 | struct parisc_rtc *p = dev_get_drvdata(dev); | ||
22 | unsigned long flags, ret; | ||
23 | |||
24 | spin_lock_irqsave(&p->lock, flags); | ||
25 | ret = get_rtc_time(tm); | ||
26 | spin_unlock_irqrestore(&p->lock, flags); | ||
27 | |||
28 | if (ret & RTC_BATT_BAD) | ||
29 | return -EOPNOTSUPP; | ||
30 | |||
31 | return 0; | ||
32 | } | ||
33 | |||
34 | static int parisc_set_time(struct device *dev, struct rtc_time *tm) | ||
35 | { | ||
36 | struct parisc_rtc *p = dev_get_drvdata(dev); | ||
37 | unsigned long flags, ret; | ||
38 | |||
39 | spin_lock_irqsave(&p->lock, flags); | ||
40 | ret = set_rtc_time(tm); | ||
41 | spin_unlock_irqrestore(&p->lock, flags); | ||
42 | |||
43 | if (ret < 0) | ||
44 | return -EOPNOTSUPP; | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static const struct rtc_class_ops parisc_rtc_ops = { | ||
50 | .read_time = parisc_get_time, | ||
51 | .set_time = parisc_set_time, | ||
52 | }; | ||
53 | |||
54 | static int __devinit parisc_rtc_probe(struct platform_device *dev) | ||
55 | { | ||
56 | struct parisc_rtc *p; | ||
57 | |||
58 | p = kzalloc(sizeof (*p), GFP_KERNEL); | ||
59 | if (!p) | ||
60 | return -ENOMEM; | ||
61 | |||
62 | spin_lock_init(&p->lock); | ||
63 | |||
64 | p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, | ||
65 | THIS_MODULE); | ||
66 | if (IS_ERR(p->rtc)) { | ||
67 | int err = PTR_ERR(p->rtc); | ||
68 | kfree(p); | ||
69 | return err; | ||
70 | } | ||
71 | |||
72 | platform_set_drvdata(dev, p); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int __devexit parisc_rtc_remove(struct platform_device *dev) | ||
78 | { | ||
79 | struct parisc_rtc *p = platform_get_drvdata(dev); | ||
80 | |||
81 | rtc_device_unregister(p->rtc); | ||
82 | kfree(p); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static struct platform_driver parisc_rtc_driver = { | ||
88 | .driver = { | ||
89 | .name = "rtc-parisc", | ||
90 | .owner = THIS_MODULE, | ||
91 | }, | ||
92 | .probe = parisc_rtc_probe, | ||
93 | .remove = __devexit_p(parisc_rtc_remove), | ||
94 | }; | ||
95 | |||
96 | static int __init parisc_rtc_init(void) | ||
97 | { | ||
98 | return platform_driver_register(&parisc_rtc_driver); | ||
99 | } | ||
100 | |||
101 | static void __exit parisc_rtc_fini(void) | ||
102 | { | ||
103 | platform_driver_unregister(&parisc_rtc_driver); | ||
104 | } | ||
105 | |||
106 | module_init(parisc_rtc_init); | ||
107 | module_exit(parisc_rtc_fini); | ||
108 | |||
109 | MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>"); | ||
110 | MODULE_LICENSE("GPL"); | ||
111 | MODULE_DESCRIPTION("HP PA-RISC RTC driver"); | ||