Messages in this thread Patch in this message |  | | Subject | [PATCH 08/10] goldfish: real time clock | From | Alan Cox <> | Date | Thu, 17 Jan 2013 17:57:00 +0000 |
| |
From: Arve Hjønnevåg <arve@google.com>
Gets the current time from the host. Alarms are not supported yet.
Signed-off-by: Mike A. Chan <mikechan@google.com> Signed-off-by: Arve Hjønnevåg <arve@android.com> [Ported to 3.4] Signed-off-by: Tom Keel <thomas.keel@intel.com> [Cleaned up to use ioremap, types, unload etc] Signed-off-by: Alan Cox <alan@linux.intel.com> ---
drivers/rtc/Kconfig | 9 +++ drivers/rtc/Makefile | 1 drivers/rtc/rtc-goldfish.c | 140 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 drivers/rtc/rtc-goldfish.c
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 1466e6a..fa5a807 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -998,6 +998,15 @@ config RTC_DRV_BFIN This driver can also be built as a module. If so, the module will be called rtc-bfin. +config RTC_DRV_GOLDFISH + tristate "GOLDFISH" + depends on GOLDFISH + help + RTC driver for Goldfish Virtual Platform + + This driver can also be built as a module. If so, the module + will be called rtc-goldfish. + config RTC_DRV_RS5C313 tristate "Ricoh RS5C313" depends on SH_LANDISK diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f774531..e24133f 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_EM3027) += rtc-em3027.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o +obj-$(CONFIG_RTC_DRV_GOLDFISH) += rtc-goldfish.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c new file mode 100644 index 0000000..c67cd9e --- /dev/null +++ b/drivers/rtc/rtc-goldfish.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2007 Google, Inc. + * Copyright (C) 2012 Intel, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> +#include <linux/export.h> +#include <linux/slab.h> + +#define GOLDFISH_TIME_LOW 0x00 +#define GOLDFISH_TIME_HIGH 0x04 +#define GOLDFISH_ALARM_LOW 0x08 +#define GOLDFISH_ALARM_HIGH 0x0C +#define GOLDFISH_CLEAR_TIMER_INT 0x10 +#define GOLDFISH_CLEAR_ALARM 0x14 + +struct goldfish_rtc { + void __iomem *base; + u32 irq; + struct rtc_device *rtc; +}; + +static irqreturn_t goldfish_rtc_interrupt(int irq, void *dev_id) +{ + struct goldfish_rtc *qrtc = dev_id; + unsigned long events = 0; + + writel(1, qrtc->base + GOLDFISH_CLEAR_TIMER_INT); + events = RTC_IRQF | RTC_AF; + + rtc_update_irq(qrtc->rtc, 1, events); + + return IRQ_HANDLED; +} + +static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + int64_t time; + struct goldfish_rtc *qrtc = platform_get_drvdata( + to_platform_device(dev)); + + time = readl(qrtc->base + GOLDFISH_TIME_LOW); + time |= (int64_t)readl(qrtc->base + GOLDFISH_TIME_HIGH) << 32; + do_div(time, NSEC_PER_SEC); + + rtc_time_to_tm(time, tm); + return 0; +} + +static const struct rtc_class_ops goldfish_rtc_ops = { + .read_time = goldfish_rtc_read_time, +}; + +static int goldfish_rtc_probe(struct platform_device *pdev) +{ + int ret; + struct resource *r; + struct goldfish_rtc *qrtc; + + qrtc = kzalloc(sizeof(*qrtc), GFP_KERNEL); + if (qrtc == NULL) { + ret = -ENOMEM; + goto err_qrtc_alloc_failed; + } + platform_set_drvdata(pdev, qrtc); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + ret = -ENODEV; + goto err_no_io_base; + } + qrtc->base = ioremap(r->start, 0x18); + if (qrtc->base == NULL) { + ret = -ENOMEM; + goto err_no_io_base; + } + qrtc->irq = platform_get_irq(pdev, 0); + if (qrtc->irq < 0) { + ret = -ENODEV; + goto err_no_irq; + } + qrtc->rtc = rtc_device_register(pdev->name, &pdev->dev, + &goldfish_rtc_ops, THIS_MODULE); + if (IS_ERR(qrtc->rtc)) { + ret = PTR_ERR(qrtc->rtc); + goto err_rtc_device_register_failed; + } + + ret = request_irq(qrtc->irq, goldfish_rtc_interrupt, 0, pdev->name, qrtc); + if (ret) + goto request_irq; + + return 0; + + free_irq(qrtc->irq, qrtc); +request_irq: + rtc_device_unregister(qrtc->rtc); +err_rtc_device_register_failed: +err_no_irq: + iounmap(qrtc->base); +err_no_io_base: + kfree(qrtc); +err_qrtc_alloc_failed: + return ret; +} + +static int goldfish_rtc_remove(struct platform_device *pdev) +{ + struct goldfish_rtc *qrtc = platform_get_drvdata(pdev); + free_irq(qrtc->irq, qrtc); + rtc_device_unregister(qrtc->rtc); + iounmap(qrtc->base); + kfree(qrtc); + return 0; +} + +static struct platform_driver goldfish_timer = { + .probe = goldfish_rtc_probe, + .remove = goldfish_rtc_remove, + .driver = { + .name = "goldfish_rtc" + } +}; + +module_platform_driver(goldfish_timer); +MODULE_LICENSE("GPL"); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |