diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rtc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 1 | ||||
-rw-r--r-- | drivers/rtc/rtc-parisc.c | 111 |
3 files changed, 120 insertions, 0 deletions
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"); | ||