From 9eb1686423756f4dfb0ad8bfb02bb8bf1b89e50a Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Wed, 10 Sep 2008 14:24:07 +0000 Subject: [PATCH] parisc: add rtc platform driver Signed-off-by: Kyle McMartin --- arch/parisc/Kconfig | 2 + arch/parisc/kernel/time.c | 20 ++++++- drivers/rtc/Kconfig | 8 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-parisc.c | 111 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 drivers/rtc/rtc-parisc.c diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index a7d4fd353c2..0a8ac703dbe 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -9,6 +9,8 @@ config PARISC def_bool y select HAVE_IDE select HAVE_OPROFILE + select RTC_CLASS + select RTC_DRV_PARISC help The PA-RISC microprocessor is designed by Hewlett-Packard and used 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 24be86bba94..4d09203bc69 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -215,6 +216,24 @@ void __init start_cpu_itimer(void) cpu_data[cpu].it_value = next_tick; } +struct platform_device rtc_parisc_dev = { + .name = "rtc-parisc", + .id = -1, +}; + +static int __init rtc_init(void) +{ + int ret; + + ret = platform_device_register(&rtc_parisc_dev); + if (ret < 0) + printk(KERN_ERR "unable to register rtc device...\n"); + + /* not necessarily an error */ + return 0; +} +module_init(rtc_init); + void __init time_init(void) { static struct pdc_tod tod_data; @@ -245,4 +264,3 @@ void __init time_init(void) xtime.tv_nsec = 0; } } - diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 9a9755c92fa..30d40fe194a 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -575,6 +575,14 @@ config RTC_DRV_RS5C313 help If you say yes here you get support for the Ricoh RS5C313 RTC chips. +config RTC_DRV_PARISC + tristate "PA-RISC firmware RTC support" + depends on PARISC + help + Say Y or M here to enable RTC support on PA-RISC systems using + firmware calls. If you do not know what you are doing, you should + just say Y. + config RTC_DRV_PPC tristate "PowerPC machine dependent RTC support" depends on PPC_MERGE diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 18622ef84ca..180ddacde73 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o +obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o 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 00000000000..346d633655e --- /dev/null +++ b/drivers/rtc/rtc-parisc.c @@ -0,0 +1,111 @@ +/* rtc-parisc: RTC for HP PA-RISC firmware + * + * Copyright (C) 2008 Kyle McMartin + */ + +#include +#include +#include +#include + +#include + +/* as simple as can be, and no simpler. */ +struct parisc_rtc { + struct rtc_device *rtc; + spinlock_t lock; +}; + +static int parisc_get_time(struct device *dev, struct rtc_time *tm) +{ + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags, ret; + + spin_lock_irqsave(&p->lock, flags); + ret = get_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); + + if (ret & RTC_BATT_BAD) + return -EOPNOTSUPP; + + return 0; +} + +static int parisc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct parisc_rtc *p = dev_get_drvdata(dev); + unsigned long flags, ret; + + spin_lock_irqsave(&p->lock, flags); + ret = set_rtc_time(tm); + spin_unlock_irqrestore(&p->lock, flags); + + if (ret < 0) + return -EOPNOTSUPP; + + return 0; +} + +static const struct rtc_class_ops parisc_rtc_ops = { + .read_time = parisc_get_time, + .set_time = parisc_set_time, +}; + +static int __devinit parisc_rtc_probe(struct platform_device *dev) +{ + struct parisc_rtc *p; + + p = kzalloc(sizeof (*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + spin_lock_init(&p->lock); + + p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops, + THIS_MODULE); + if (IS_ERR(p->rtc)) { + int err = PTR_ERR(p->rtc); + kfree(p); + return err; + } + + platform_set_drvdata(dev, p); + + return 0; +} + +static int __devexit parisc_rtc_remove(struct platform_device *dev) +{ + struct parisc_rtc *p = platform_get_drvdata(dev); + + rtc_device_unregister(p->rtc); + kfree(p); + + return 0; +} + +static struct platform_driver parisc_rtc_driver = { + .driver = { + .name = "rtc-parisc", + .owner = THIS_MODULE, + }, + .probe = parisc_rtc_probe, + .remove = __devexit_p(parisc_rtc_remove), +}; + +static int __init parisc_rtc_init(void) +{ + return platform_driver_register(&parisc_rtc_driver); +} + +static void __exit parisc_rtc_fini(void) +{ + platform_driver_unregister(&parisc_rtc_driver); +} + +module_init(parisc_rtc_init); +module_exit(parisc_rtc_fini); + +MODULE_AUTHOR("Kyle McMartin "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("HP PA-RISC RTC driver"); -- 2.41.1