From fdf8afa188595e2f6c39f6a05ea147f48621a996 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 6 May 2015 09:24:42 +0200 Subject: rtc: xgene: Set hardware dependency The rtc-xgene driver is only useful on X-Gene SoC. Signed-off-by: Jean Delvare Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Iyappan Subramanian Cc: Keyur Chudgar Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0fe4ad8826b2..b957b4f67f0f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1533,6 +1533,7 @@ config RTC_DRV_MOXART config RTC_DRV_XGENE tristate "APM X-Gene RTC" depends on HAS_IOMEM + depends on ARCH_XGENE || COMPILE_TEST help If you say yes here you get support for the APM X-Gene SoC real time clock. -- cgit v1.2.3 From fc2979118f3f5193475cb53d5df7bdaa7e358a42 Mon Sep 17 00:00:00 2001 From: Tianping Fang Date: Wed, 6 May 2015 15:23:41 +0800 Subject: rtc: mediatek: Add MT6397 RTC driver Add Mediatek MT6397 RTC driver Signed-off-by: Tianping Fang Signed-off-by: Eddie Huang Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-mt6397.c | 394 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 405 insertions(+) create mode 100644 drivers/rtc/rtc-mt6397.c (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b957b4f67f0f..20a1f35dc0d5 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1530,6 +1530,16 @@ config RTC_DRV_MOXART This driver can also be built as a module. If so, the module will be called rtc-moxart +config RTC_DRV_MT6397 + tristate "Mediatek Real Time Clock driver" + depends on MFD_MT6397 || COMPILE_TEST + help + This selects the Mediatek(R) RTC driver. RTC is part of Mediatek + MT6397 PMIC. You should enable MT6397 PMIC MFD before select + Mediatek(R) RTC driver. + + If you want to use Mediatek(R) RTC interface, select Y or M here. + config RTC_DRV_XGENE tristate "APM X-Gene RTC" depends on HAS_IOMEM diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 2b82e2b0311b..371d97795fb5 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -155,3 +155,4 @@ obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o obj-$(CONFIG_RTC_DRV_XGENE) += rtc-xgene.o obj-$(CONFIG_RTC_DRV_SIRFSOC) += rtc-sirfsoc.o obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o +obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c new file mode 100644 index 000000000000..8bed852e4961 --- /dev/null +++ b/drivers/rtc/rtc-mt6397.c @@ -0,0 +1,394 @@ +/* +* Copyright (c) 2014-2015 MediaTek Inc. +* Author: Tianping.Fang +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RTC_BBPU 0x0000 +#define RTC_BBPU_CBUSY BIT(6) + +#define RTC_WRTGR 0x003c + +#define RTC_IRQ_STA 0x0002 +#define RTC_IRQ_STA_AL BIT(0) +#define RTC_IRQ_STA_LP BIT(3) + +#define RTC_IRQ_EN 0x0004 +#define RTC_IRQ_EN_AL BIT(0) +#define RTC_IRQ_EN_ONESHOT BIT(2) +#define RTC_IRQ_EN_LP BIT(3) +#define RTC_IRQ_EN_ONESHOT_AL (RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL) + +#define RTC_AL_MASK 0x0008 +#define RTC_AL_MASK_DOW BIT(4) + +#define RTC_TC_SEC 0x000a +/* Min, Hour, Dom... register offset to RTC_TC_SEC */ +#define RTC_OFFSET_SEC 0 +#define RTC_OFFSET_MIN 1 +#define RTC_OFFSET_HOUR 2 +#define RTC_OFFSET_DOM 3 +#define RTC_OFFSET_DOW 4 +#define RTC_OFFSET_MTH 5 +#define RTC_OFFSET_YEAR 6 +#define RTC_OFFSET_COUNT 7 + +#define RTC_AL_SEC 0x0018 + +#define RTC_PDN2 0x002e +#define RTC_PDN2_PWRON_ALARM BIT(4) + +#define RTC_MIN_YEAR 1968 +#define RTC_BASE_YEAR 1900 +#define RTC_NUM_YEARS 128 +#define RTC_MIN_YEAR_OFFSET (RTC_MIN_YEAR - RTC_BASE_YEAR) + +struct mt6397_rtc { + struct device *dev; + struct rtc_device *rtc_dev; + struct mutex lock; + struct regmap *regmap; + int irq; + u32 addr_base; +}; + +static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) +{ + unsigned long timeout = jiffies + HZ; + int ret; + u32 data; + + ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1); + if (ret < 0) + return ret; + + while (1) { + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU, + &data); + if (ret < 0) + break; + if (!(data & RTC_BBPU_CBUSY)) + break; + if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; + break; + } + cpu_relax(); + } + + return ret; +} + +static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data) +{ + struct mt6397_rtc *rtc = data; + u32 irqsta, irqen; + int ret; + + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_STA, &irqsta); + if ((ret >= 0) && (irqsta & RTC_IRQ_STA_AL)) { + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + irqen = irqsta & ~RTC_IRQ_EN_AL; + mutex_lock(&rtc->lock); + if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, + irqen) < 0) + mtk_rtc_write_trigger(rtc); + mutex_unlock(&rtc->lock); + + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int __mtk_rtc_read_time(struct mt6397_rtc *rtc, + struct rtc_time *tm, int *sec) +{ + int ret; + u16 data[RTC_OFFSET_COUNT]; + + mutex_lock(&rtc->lock); + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + + tm->tm_sec = data[RTC_OFFSET_SEC]; + tm->tm_min = data[RTC_OFFSET_MIN]; + tm->tm_hour = data[RTC_OFFSET_HOUR]; + tm->tm_mday = data[RTC_OFFSET_DOM]; + tm->tm_mon = data[RTC_OFFSET_MTH]; + tm->tm_year = data[RTC_OFFSET_YEAR]; + + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec); +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + time64_t time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int sec, ret; + + do { + ret = __mtk_rtc_read_time(rtc, tm, &sec); + if (ret < 0) + goto exit; + } while (sec < tm->tm_sec); + + /* HW register use 7 bits to store year data, minus + * RTC_MIN_YEAR_OFFSET before write year data to register, and plus + * RTC_MIN_YEAR_OFFSET back after read year from register + */ + tm->tm_year += RTC_MIN_YEAR_OFFSET; + + /* HW register start mon from one, but tm_mon start from zero. */ + tm->tm_mon--; + time = rtc_tm_to_time64(tm); + + /* rtc_tm_to_time64 covert Gregorian date to seconds since + * 01-01-1970 00:00:00, and this date is Thursday. + */ + tm->tm_wday = (time / 86400 + 4) % 7; + +exit: + return ret; +} + +static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + tm->tm_year -= RTC_MIN_YEAR_OFFSET; + tm->tm_mon++; + + data[RTC_OFFSET_SEC] = tm->tm_sec; + data[RTC_OFFSET_MIN] = tm->tm_min; + data[RTC_OFFSET_HOUR] = tm->tm_hour; + data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_MTH] = tm->tm_mon; + data[RTC_OFFSET_YEAR] = tm->tm_year; + + mutex_lock(&rtc->lock); + ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + + /* Time register write to hardware after call trigger function */ + ret = mtk_rtc_write_trigger(rtc); + +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + u32 irqen, pdn2; + int ret; + u16 data[RTC_OFFSET_COUNT]; + + mutex_lock(&rtc->lock); + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, &irqen); + if (ret < 0) + goto err_exit; + ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_PDN2, &pdn2); + if (ret < 0) + goto err_exit; + + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto err_exit; + + alm->enabled = !!(irqen & RTC_IRQ_EN_AL); + alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM); + mutex_unlock(&rtc->lock); + + tm->tm_sec = data[RTC_OFFSET_SEC]; + tm->tm_min = data[RTC_OFFSET_MIN]; + tm->tm_hour = data[RTC_OFFSET_HOUR]; + tm->tm_mday = data[RTC_OFFSET_DOM]; + tm->tm_mon = data[RTC_OFFSET_MTH]; + tm->tm_year = data[RTC_OFFSET_YEAR]; + + tm->tm_year += RTC_MIN_YEAR_OFFSET; + tm->tm_mon--; + + return 0; +err_exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time *tm = &alm->time; + struct mt6397_rtc *rtc = dev_get_drvdata(dev); + int ret; + u16 data[RTC_OFFSET_COUNT]; + + tm->tm_year -= RTC_MIN_YEAR_OFFSET; + tm->tm_mon++; + + data[RTC_OFFSET_SEC] = tm->tm_sec; + data[RTC_OFFSET_MIN] = tm->tm_min; + data[RTC_OFFSET_HOUR] = tm->tm_hour; + data[RTC_OFFSET_DOM] = tm->tm_mday; + data[RTC_OFFSET_MTH] = tm->tm_mon; + data[RTC_OFFSET_YEAR] = tm->tm_year; + + mutex_lock(&rtc->lock); + if (alm->enabled) { + ret = regmap_bulk_write(rtc->regmap, + rtc->addr_base + RTC_AL_SEC, + data, RTC_OFFSET_COUNT); + if (ret < 0) + goto exit; + ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_AL_MASK, + RTC_AL_MASK_DOW); + if (ret < 0) + goto exit; + ret = regmap_update_bits(rtc->regmap, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_ONESHOT_AL, + RTC_IRQ_EN_ONESHOT_AL); + if (ret < 0) + goto exit; + } else { + ret = regmap_update_bits(rtc->regmap, + rtc->addr_base + RTC_IRQ_EN, + RTC_IRQ_EN_ONESHOT_AL, 0); + if (ret < 0) + goto exit; + } + + /* All alarm time register write to hardware after calling + * mtk_rtc_write_trigger. This can avoid race condition if alarm + * occur happen during writing alarm time register. + */ + ret = mtk_rtc_write_trigger(rtc); +exit: + mutex_unlock(&rtc->lock); + return ret; +} + +static struct rtc_class_ops mtk_rtc_ops = { + .read_time = mtk_rtc_read_time, + .set_time = mtk_rtc_set_time, + .read_alarm = mtk_rtc_read_alarm, + .set_alarm = mtk_rtc_set_alarm, +}; + +static int mtk_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent); + struct mt6397_rtc *rtc; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->addr_base = res->start; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start); + if (rtc->irq <= 0) + return -EINVAL; + + rtc->regmap = mt6397_chip->regmap; + rtc->dev = &pdev->dev; + mutex_init(&rtc->lock); + + platform_set_drvdata(pdev, rtc); + + ret = request_threaded_irq(rtc->irq, NULL, + mtk_rtc_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + "mt6397-rtc", rtc); + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + rtc->irq, ret); + goto out_dispose_irq; + } + + rtc->rtc_dev = rtc_device_register("mt6397-rtc", &pdev->dev, + &mtk_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc_dev)) { + dev_err(&pdev->dev, "register rtc device failed\n"); + ret = PTR_ERR(rtc->rtc_dev); + goto out_free_irq; + } + + device_init_wakeup(&pdev->dev, 1); + + return 0; + +out_free_irq: + free_irq(rtc->irq, rtc->rtc_dev); +out_dispose_irq: + irq_dispose_mapping(rtc->irq); + return ret; +} + +static int mtk_rtc_remove(struct platform_device *pdev) +{ + struct mt6397_rtc *rtc = platform_get_drvdata(pdev); + + rtc_device_unregister(rtc->rtc_dev); + free_irq(rtc->irq, rtc->rtc_dev); + irq_dispose_mapping(rtc->irq); + + return 0; +} + +static const struct of_device_id mt6397_rtc_of_match[] = { + { .compatible = "mediatek,mt6397-rtc", }, + { } +}; + +static struct platform_driver mtk_rtc_driver = { + .driver = { + .name = "mt6397-rtc", + .of_match_table = mt6397_rtc_of_match, + }, + .probe = mtk_rtc_probe, + .remove = mtk_rtc_remove, +}; + +module_platform_driver(mtk_rtc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Tianping Fang "); +MODULE_DESCRIPTION("RTC Driver for MediaTek MT6397 PMIC"); +MODULE_ALIAS("platform:mt6397-rtc"); -- cgit v1.2.3 From 20d048ac8ba160747be5dbe00b7cbcfda762d25f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 3 May 2015 11:29:44 +0200 Subject: rtc: stmp3xxx select STMP_DEVICE rtc-stmp3xxx depends on lib/stmp_device, select it. Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 20a1f35dc0d5..3eff65d7a496 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1396,6 +1396,7 @@ config RTC_DRV_COH901331 config RTC_DRV_STMP tristate "Freescale STMP3xxx/i.MX23/i.MX28 RTC" depends on ARCH_MXS + select STMP_DEVICE help If you say yes here you will get support for the onboard STMP3xxx/i.MX23/i.MX28 RTC. -- cgit v1.2.3 From 98a9bb5bf44bb6ee372f2a3b42703f597030cc48 Mon Sep 17 00:00:00 2001 From: Hans Ulli Kroll Date: Wed, 20 May 2015 17:49:31 +0200 Subject: rtc: driver for Cortina Gemini Driver for the on chip RTC found on Cortina's SoC Gemini. Signed-off-by: Hans Ulli Kroll [alexandre.belloni@free-electrons.com: use devm_request_irq() and remove useless goto] Signed-off-by: Alexandre Belloni --- MAINTAINERS | 1 + drivers/rtc/Kconfig | 11 +++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-gemini.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 drivers/rtc/rtc-gemini.c (limited to 'drivers/rtc/Kconfig') diff --git a/MAINTAINERS b/MAINTAINERS index 8fc34fa78dcb..16df5b1035b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -977,6 +977,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) T: git git://github.com/ulli-kroll/linux.git S: Maintained F: arch/arm/mach-gemini/ +F: drivers/rtc/rtc-gemini.c ARM/CSR SIRFPRIMA2 MACHINE SUPPORT M: Barry Song diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 3eff65d7a496..c94bb6aded51 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1372,6 +1372,17 @@ config RTC_DRV_ARMADA38X This driver can also be built as a module. If so, the module will be called armada38x-rtc. +config RTC_DRV_GEMINI + tristate "Gemini SoC RTC" + depends on ARCH_GEMINI || COMPILE_TEST + depends on HAS_IOMEM + help + If you say Y here you will get support for the + RTC found on Gemini SoC's. + + This driver can also be built as a module. If so, the module + will be called rtc-gemini. + config RTC_DRV_PS3 tristate "PS3 RTC" depends on PPC_PS3 diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 371d97795fb5..7cc7cecc3864 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o 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_GEMINI) += rtc-gemini.o obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c new file mode 100644 index 000000000000..5fc17df27c99 --- /dev/null +++ b/drivers/rtc/rtc-gemini.c @@ -0,0 +1,176 @@ +/* + * Gemini OnChip RTC + * + * Copyright (C) 2009 Janos Laube + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * Original code for older kernel 2.6.15 are from Stormlinksemi + * first update from Janos Laube for > 2.6.29 kernels + * + * checkpatch fixes and usage of rtc-lib code + * Hans Ulli Kroll + */ + +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "rtc-gemini" +#define DRV_VERSION "0.2" + +MODULE_AUTHOR("Hans Ulli Kroll "); +MODULE_DESCRIPTION("RTC driver for Gemini SoC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); + +struct gemini_rtc { + struct rtc_device *rtc_dev; + void __iomem *rtc_base; + int rtc_irq; +}; + +enum gemini_rtc_offsets { + GEMINI_RTC_SECOND = 0x00, + GEMINI_RTC_MINUTE = 0x04, + GEMINI_RTC_HOUR = 0x08, + GEMINI_RTC_DAYS = 0x0C, + GEMINI_RTC_ALARM_SECOND = 0x10, + GEMINI_RTC_ALARM_MINUTE = 0x14, + GEMINI_RTC_ALARM_HOUR = 0x18, + GEMINI_RTC_RECORD = 0x1C, + GEMINI_RTC_CR = 0x20 +}; + +static irqreturn_t gemini_rtc_interrupt(int irq, void *dev) +{ + return IRQ_HANDLED; +} + +/* + * Looks like the RTC in the Gemini SoC is (totaly) broken + * We can't read/write directly the time from RTC registers. + * We must do some "offset" calculation to get the real time + * + * This FIX works pretty fine and Stormlinksemi aka Cortina-Networks does + * the same thing, without the rtc-lib.c calls. + */ + +static int gemini_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct gemini_rtc *rtc = dev_get_drvdata(dev); + + unsigned int days, hour, min, sec; + unsigned long offset, time; + + sec = readl(rtc->rtc_base + GEMINI_RTC_SECOND); + min = readl(rtc->rtc_base + GEMINI_RTC_MINUTE); + hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR); + days = readl(rtc->rtc_base + GEMINI_RTC_DAYS); + offset = readl(rtc->rtc_base + GEMINI_RTC_RECORD); + + time = offset + days * 86400 + hour * 3600 + min * 60 + sec; + + rtc_time_to_tm(time, tm); + + return 0; +} + +static int gemini_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct gemini_rtc *rtc = dev_get_drvdata(dev); + unsigned int sec, min, hour, day; + unsigned long offset, time; + + if (tm->tm_year >= 2148) /* EPOCH Year + 179 */ + return -EINVAL; + + rtc_tm_to_time(tm, &time); + + sec = readl(rtc->rtc_base + GEMINI_RTC_SECOND); + min = readl(rtc->rtc_base + GEMINI_RTC_MINUTE); + hour = readl(rtc->rtc_base + GEMINI_RTC_HOUR); + day = readl(rtc->rtc_base + GEMINI_RTC_DAYS); + + offset = time - (day * 86400 + hour * 3600 + min * 60 + sec); + + writel(offset, rtc->rtc_base + GEMINI_RTC_RECORD); + writel(0x01, rtc->rtc_base + GEMINI_RTC_CR); + + return 0; +} + +static struct rtc_class_ops gemini_rtc_ops = { + .read_time = gemini_rtc_read_time, + .set_time = gemini_rtc_set_time, +}; + +static int gemini_rtc_probe(struct platform_device *pdev) +{ + struct gemini_rtc *rtc; + struct device *dev = &pdev->dev; + struct resource *res; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (unlikely(!rtc)) + return -ENOMEM; + platform_set_drvdata(pdev, rtc); + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) + return -ENODEV; + + rtc->rtc_irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + rtc->rtc_base = devm_ioremap(dev, res->start, + res->end - res->start + 1); + + ret = devm_request_irq(dev, rtc->rtc_irq, gemini_rtc_interrupt, + IRQF_SHARED, pdev->name, dev); + if (unlikely(ret)) + return ret; + + rtc->rtc_dev = rtc_device_register(pdev->name, dev, + &gemini_rtc_ops, THIS_MODULE); + if (likely(IS_ERR(rtc->rtc_dev))) + return PTR_ERR(rtc->rtc_dev); + + return 0; +} + +static int gemini_rtc_remove(struct platform_device *pdev) +{ + struct gemini_rtc *rtc = platform_get_drvdata(pdev); + + rtc_device_unregister(rtc->rtc_dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver gemini_rtc_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = gemini_rtc_probe, + .remove = gemini_rtc_remove, +}; + +module_platform_driver_probe(gemini_rtc_driver, gemini_rtc_probe); -- cgit v1.2.3 From 9c5150b31b49e3d89c52df9b1c1ebcea4e665ec3 Mon Sep 17 00:00:00 2001 From: Xunlei Pang Date: Fri, 12 Jun 2015 11:10:16 +0800 Subject: rtc: NTP: Add CONFIG_RTC_SYSTOHC_DEVICE for NTP synchronization Currently, CONFIG_RTC_SYSTOHC uses CONFIG_RTC_HCTOSYS_DEVICE which is originally used by CONFIG_RTC_HCTOSYS, but this rtc device has some limiations, for example, it must be battery-backed, be able to work with irq off and through system suspension, etc. So add CONFIG_RTC_SYSTOHC_DEVICE used exclusively for CONFIG_RTC_SYSTOHC, it is more lenient compared to CONFIG_RTC_HCTOSYS_DEVICE, and could be assigned any available RTC in the system. Default value is CONFIG_RTC_HCTOSYS_DEVICE which is "rtc0" by default. After this patch, NTP will sync up "rtc0" by default. Cc: Paul Bolle Signed-off-by: Xunlei Pang Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 29 ++++++++++++++++++++--------- drivers/rtc/systohc.c | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index c94bb6aded51..efaff368ee94 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -25,17 +25,9 @@ config RTC_HCTOSYS the value read from a specified RTC device. This is useful to avoid unnecessary fsck runs at boot time, and to network better. -config RTC_SYSTOHC - bool "Set the RTC time based on NTP synchronization" - default y - help - If you say yes here, the system time (wall clock) will be stored - in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 - minutes if userspace reports synchronized NTP status. - config RTC_HCTOSYS_DEVICE string "RTC used to set the system time" - depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y + depends on RTC_HCTOSYS default "rtc0" help The RTC device that will be used to (re)initialize the system @@ -56,6 +48,25 @@ config RTC_HCTOSYS_DEVICE sleep states. Do not specify an RTC here unless it stays powered during all this system's supported sleep states. +config RTC_SYSTOHC + bool "Set the RTC time based on NTP synchronization" + default y + help + If you say yes here, the system time (wall clock) will be stored + in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11 + minutes if userspace reports synchronized NTP status. + +config RTC_SYSTOHC_DEVICE + string "RTC used to synchronize NTP adjustment" + depends on RTC_SYSTOHC + default RTC_HCTOSYS_DEVICE if RTC_HCTOSYS + default "rtc0" + help + The RTC device used for NTP synchronization. The main difference + between RTC_HCTOSYS_DEVICE and RTC_SYSTOHC_DEVICE is that this + one can sleep when setting time, because it runs in the workqueue + context. + config RTC_DEBUG bool "RTC debug support" help diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index 7728d5e32bf4..b4a68ffcd06b 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -31,7 +31,7 @@ int rtc_set_ntp_time(struct timespec64 now) else rtc_time64_to_tm(now.tv_sec + 1, &tm); - rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + rtc = rtc_class_open(CONFIG_RTC_SYSTOHC_DEVICE); if (rtc) { /* rtc_hctosys exclusively uses UTC, so we call set_time here, * not set_mmss. */ -- cgit v1.2.3 From 98ab2c938c7f77741ed09ee8ce21e8d7770669ef Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 9 May 2015 21:21:54 +0200 Subject: rtc: whitespace fixes Some entries in the Kconfig are improperly indented with spaces instead of tabs. Also fix whitespaces in Makefile. Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 48 ++++++++++++++++++++++++------------------------ drivers/rtc/Makefile | 12 ++++++------ 2 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index efaff368ee94..6db0a9d75f8d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -12,7 +12,7 @@ menuconfig RTC_CLASS select RTC_LIB help Generic RTC class support. If you say yes here, you will - be allowed to plug one or more RTCs to your system. You will + be allowed to plug one or more RTCs to your system. You will probably want to enable one or more of the interfaces below. if RTC_CLASS @@ -165,10 +165,10 @@ config RTC_DRV_88PM80X will be called rtc-88pm80x. config RTC_DRV_ABB5ZES3 - depends on I2C - select REGMAP_I2C - tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" - help + depends on I2C + select REGMAP_I2C + tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" + help If you say yes here you get support for the Abracon AB-RTCMC-32.768kHz-B5ZE-S3 I2C RTC chip. @@ -376,10 +376,10 @@ config RTC_DRV_ISL12022 will be called rtc-isl12022. config RTC_DRV_ISL12057 - depends on I2C - select REGMAP_I2C - tristate "Intersil ISL12057" - help + depends on I2C + select REGMAP_I2C + tristate "Intersil ISL12057" + help If you say yes here you get support for the Intersil ISL12057 I2C RTC chip. @@ -614,13 +614,13 @@ comment "SPI RTC drivers" if SPI_MASTER config RTC_DRV_M41T93 - tristate "ST M41T93" - help - If you say yes here you will get support for the - ST M41T93 SPI RTC chip. + tristate "ST M41T93" + help + If you say yes here you will get support for the + ST M41T93 SPI RTC chip. - This driver can also be built as a module. If so, the module - will be called rtc-m41t93. + This driver can also be built as a module. If so, the module + will be called rtc-m41t93. config RTC_DRV_M41T94 tristate "ST M41T94" @@ -1211,7 +1211,7 @@ config RTC_DRV_SH Say Y here to enable support for the on-chip RTC found in most SuperH processors. - To compile this driver as a module, choose M here: the + To compile this driver as a module, choose M here: the module will be called rtc-sh. config RTC_DRV_VR41XX @@ -1310,14 +1310,14 @@ config RTC_DRV_GENERIC just say Y. config RTC_DRV_PXA - tristate "PXA27x/PXA3xx" - depends on ARCH_PXA - help - If you say Y here you will get access to the real time clock - built into your PXA27x or PXA3xx CPU. - - This RTC driver uses PXA RTC registers available since pxa27x - series (RDxR, RYxR) instead of legacy RCNR, RTAR. + tristate "PXA27x/PXA3xx" + depends on ARCH_PXA + help + If you say Y here you will get access to the real time clock + built into your PXA27x or PXA3xx CPU. + + This RTC driver uses PXA RTC registers available since pxa27x + series (RDxR, RYxR) instead of legacy RCNR, RTAR. config RTC_DRV_VT8500 tristate "VIA/WonderMedia 85xx SoC RTC" diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 5a893dd9e55d..5ea5370f56f2 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -14,14 +14,14 @@ ifdef CONFIG_RTC_DRV_EFI rtc-core-y += rtc-efi-platform.o endif -rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o -rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o +rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o +rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o +rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. obj-$(CONFIG_RTC_DRV_88PM80X) += rtc-88pm80x.o -obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o +obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_ABB5ZES3) += rtc-ab-b5ze-s3.o @@ -57,7 +57,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1685_FAMILY) += rtc-ds1685.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o -obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o +obj-$(CONFIG_RTC_DRV_DS2404) += rtc-ds2404.o obj-$(CONFIG_RTC_DRV_DS3232) += rtc-ds3232.o obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o @@ -85,7 +85,7 @@ obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_MAX77686) += rtc-max77686.o -obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o +obj-$(CONFIG_RTC_DRV_MAX77802) += rtc-max77802.o obj-$(CONFIG_RTC_DRV_MAX8907) += rtc-max8907.o obj-$(CONFIG_RTC_DRV_MAX8925) += rtc-max8925.o obj-$(CONFIG_RTC_DRV_MAX8997) += rtc-max8997.o -- cgit v1.2.3 From 3783055ef4cf096910f670f9a1a32e32db08559b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 8 Jun 2015 19:27:37 +0200 Subject: rtc: remove useless I2C dependencies Multiple options depend on I2C but are already under under if I2C. Remove those useless dependencies. Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/rtc/Kconfig') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6db0a9d75f8d..ca3432c83333 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -146,7 +146,7 @@ if I2C config RTC_DRV_88PM860X tristate "Marvell 88PM860x" - depends on I2C && MFD_88PM860X + depends on MFD_88PM860X help If you say yes here you get support for RTC function in Marvell 88PM860x chips. @@ -156,7 +156,7 @@ config RTC_DRV_88PM860X config RTC_DRV_88PM80X tristate "Marvell 88PM80x" - depends on I2C && MFD_88PM800 + depends on MFD_88PM800 help If you say yes here you get support for RTC function in Marvell 88PM80x chips. @@ -165,7 +165,6 @@ config RTC_DRV_88PM80X will be called rtc-88pm80x. config RTC_DRV_ABB5ZES3 - depends on I2C select REGMAP_I2C tristate "Abracon AB-RTCMC-32.768kHz-B5ZE-S3" help @@ -215,7 +214,6 @@ config RTC_DRV_DS1307 config RTC_DRV_DS1374 tristate "Dallas/Maxim DS1374" - depends on I2C help If you say yes here you get support for Dallas Semiconductor DS1374 real-time clock chips. If an interrupt is associated @@ -243,7 +241,6 @@ config RTC_DRV_DS1672 config RTC_DRV_DS3232 tristate "Dallas/Maxim DS3232" - depends on I2C help If you say yes here you get support for Dallas Semiconductor DS3232 real-time clock chips. If an interrupt is associated @@ -254,7 +251,7 @@ config RTC_DRV_DS3232 config RTC_DRV_HYM8563 tristate "Haoyu Microelectronics HYM8563" - depends on I2C && OF + depends on OF help Say Y to enable support for the HYM8563 I2C RTC chip. Apart from the usual rtc functions it provides a clock output of @@ -376,7 +373,6 @@ config RTC_DRV_ISL12022 will be called rtc-isl12022. config RTC_DRV_ISL12057 - depends on I2C select REGMAP_I2C tristate "Intersil ISL12057" help -- cgit v1.2.3