Commit 9eb1686423756f4dfb0ad8bfb02bb8bf1b89e50a

Authored by Kyle McMartin
Committed by Kyle McMartin
1 parent f0514ae323

parisc: add rtc platform driver

Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>

Showing 5 changed files with 141 additions and 1 deletions Side-by-side Diff

... ... @@ -9,6 +9,8 @@
9 9 def_bool y
10 10 select HAVE_IDE
11 11 select HAVE_OPROFILE
  12 + select RTC_CLASS
  13 + select RTC_DRV_PARISC
12 14 help
13 15 The PA-RISC microprocessor is designed by Hewlett-Packard and used
14 16 in many of their workstations & servers (HP9000 700 and 800 series,
arch/parisc/kernel/time.c
... ... @@ -23,6 +23,7 @@
23 23 #include <linux/smp.h>
24 24 #include <linux/profile.h>
25 25 #include <linux/clocksource.h>
  26 +#include <linux/platform_device.h>
26 27  
27 28 #include <asm/uaccess.h>
28 29 #include <asm/io.h>
... ... @@ -214,6 +215,24 @@
214 215  
215 216 cpu_data[cpu].it_value = next_tick;
216 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);
217 236  
218 237 void __init time_init(void)
219 238 {
... ... @@ -575,6 +575,14 @@
575 575 help
576 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 586 config RTC_DRV_PPC
579 587 tristate "PowerPC machine dependent RTC support"
580 588 depends on PPC_MERGE
drivers/rtc/Makefile
... ... @@ -45,6 +45,7 @@
45 45 obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
46 46 obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
47 47 obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
  48 +obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o
48 49 obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
49 50 obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
50 51 obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
drivers/rtc/rtc-parisc.c
  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");