blob: cb087ad407f60af50b0be1e6b2ec44e12d6fa851 [file] [log] [blame]
Kyle McMartin9eb16862008-09-10 14:24:07 +00001/* 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>
dann frazier93d456d2009-03-31 15:24:49 -070010#include <linux/rtc.h>
Kyle McMartin9eb16862008-09-10 14:24:07 +000011
12#include <asm/rtc.h>
13
14/* as simple as can be, and no simpler. */
15struct parisc_rtc {
16 struct rtc_device *rtc;
Kyle McMartin9eb16862008-09-10 14:24:07 +000017};
18
19static int parisc_get_time(struct device *dev, struct rtc_time *tm)
20{
dann frazier05439f12009-03-31 15:24:50 -070021 unsigned long ret;
Kyle McMartin9eb16862008-09-10 14:24:07 +000022
Kyle McMartin9eb16862008-09-10 14:24:07 +000023 ret = get_rtc_time(tm);
Kyle McMartin9eb16862008-09-10 14:24:07 +000024
25 if (ret & RTC_BATT_BAD)
26 return -EOPNOTSUPP;
27
28 return 0;
29}
30
31static int parisc_set_time(struct device *dev, struct rtc_time *tm)
32{
Roel Kluin022b7692008-12-03 04:16:04 +000033 int ret;
Kyle McMartin9eb16862008-09-10 14:24:07 +000034
Kyle McMartin9eb16862008-09-10 14:24:07 +000035 ret = set_rtc_time(tm);
Kyle McMartin9eb16862008-09-10 14:24:07 +000036
37 if (ret < 0)
38 return -EOPNOTSUPP;
39
40 return 0;
41}
42
43static const struct rtc_class_ops parisc_rtc_ops = {
44 .read_time = parisc_get_time,
45 .set_time = parisc_set_time,
46};
47
48static int __devinit parisc_rtc_probe(struct platform_device *dev)
49{
50 struct parisc_rtc *p;
51
52 p = kzalloc(sizeof (*p), GFP_KERNEL);
53 if (!p)
54 return -ENOMEM;
55
Kyle McMartin9eb16862008-09-10 14:24:07 +000056 p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
57 THIS_MODULE);
58 if (IS_ERR(p->rtc)) {
59 int err = PTR_ERR(p->rtc);
60 kfree(p);
61 return err;
62 }
63
64 platform_set_drvdata(dev, p);
65
66 return 0;
67}
68
69static int __devexit parisc_rtc_remove(struct platform_device *dev)
70{
71 struct parisc_rtc *p = platform_get_drvdata(dev);
72
73 rtc_device_unregister(p->rtc);
74 kfree(p);
75
76 return 0;
77}
78
79static struct platform_driver parisc_rtc_driver = {
80 .driver = {
81 .name = "rtc-parisc",
82 .owner = THIS_MODULE,
83 },
84 .probe = parisc_rtc_probe,
85 .remove = __devexit_p(parisc_rtc_remove),
86};
87
88static int __init parisc_rtc_init(void)
89{
90 return platform_driver_register(&parisc_rtc_driver);
91}
92
93static void __exit parisc_rtc_fini(void)
94{
95 platform_driver_unregister(&parisc_rtc_driver);
96}
97
98module_init(parisc_rtc_init);
99module_exit(parisc_rtc_fini);
100
101MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
102MODULE_LICENSE("GPL");
103MODULE_DESCRIPTION("HP PA-RISC RTC driver");