diff options
Diffstat (limited to 'drivers/rtc')
37 files changed, 717 insertions, 418 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b5b5c3d485d6..6149ae01e11f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1111,6 +1111,16 @@ config RTC_DRV_DAVINCI This driver can also be built as a module. If so, the module will be called rtc-davinci. +config RTC_DRV_DIGICOLOR + tristate "Conexant Digicolor RTC" + depends on ARCH_DIGICOLOR + help + If you say yes here you get support for the RTC on Conexant + Digicolor platforms. This currently includes the CX92755 SoC. + + This driver can also be built as a module. If so, the module + will be called rtc-digicolor. + config RTC_DRV_IMXDI tristate "Freescale IMX DryIce Real Time Clock" depends on ARCH_MXC @@ -1121,11 +1131,11 @@ config RTC_DRV_IMXDI will be called "rtc-imxdi". config RTC_DRV_OMAP - tristate "TI OMAP1" - depends on ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_DAVINCI_DA8XX || SOC_AM33XX + tristate "TI OMAP Real Time Clock" + depends on ARCH_OMAP || ARCH_DAVINCI help Say "yes" here to support the on chip real time clock - present on TI OMAP1, AM33xx and DA8xx/OMAP-L13x. + present on TI OMAP1, AM33xx, DA8xx/OMAP-L13x, AM43xx and DRA7xx. This driver can also be built as a module, if so, module will be called rtc-omap. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 69c87062b098..c31731c29762 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o obj-$(CONFIG_RTC_DRV_DAVINCI) += rtc-davinci.o +obj-$(CONFIG_RTC_DRV_DIGICOLOR) += rtc-digicolor.o obj-$(CONFIG_RTC_DRV_DM355EVM) += rtc-dm355evm.o obj-$(CONFIG_RTC_DRV_VRTC) += rtc-mrst.o obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 472a5adc4642..ea2a315df6b7 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -55,7 +55,7 @@ static int rtc_suspend(struct device *dev) struct timespec64 delta, delta_delta; int err; - if (has_persistent_clock()) + if (timekeeping_rtc_skipsuspend()) return 0; if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0) @@ -102,7 +102,7 @@ static int rtc_resume(struct device *dev) struct timespec64 sleep_time; int err; - if (has_persistent_clock()) + if (timekeeping_rtc_skipresume()) return 0; rtc_hctosys_ret = -ENODEV; @@ -117,10 +117,6 @@ static int rtc_resume(struct device *dev) return 0; } - if (rtc_valid_tm(&tm) != 0) { - pr_debug("%s: bogus resume time\n", dev_name(&rtc->dev)); - return 0; - } new_rtc.tv_sec = rtc_tm_to_time64(&tm); new_rtc.tv_nsec = 0; @@ -225,15 +221,15 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->pie_timer.function = rtc_pie_update_irq; rtc->pie_enabled = 0; + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); + dev_set_name(&rtc->dev, "rtc%d", id); + /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); if (!err && !rtc_valid_tm(&alrm.time)) rtc_initialize_alarm(rtc, &alrm); - strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); - dev_set_name(&rtc->dev, "rtc%d", id); - rtc_dev_prepare(rtc); err = device_register(&rtc->dev); diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index 6c719f23520a..e1cfa06810ef 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -9,6 +9,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/rtc.h> /* IMPORTANT: the RTC only stores whole seconds. It is arbitrary @@ -32,8 +34,8 @@ static int __init rtc_hctosys(void) struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); if (rtc == NULL) { - pr_err("%s: unable to open rtc device (%s)\n", - __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); + pr_info("unable to open rtc device (%s)\n", + CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; } diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 37215cf983e9..166fc60d8b55 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -31,13 +31,14 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) memset(tm, 0, sizeof(struct rtc_time)); err = rtc->ops->read_time(rtc->dev.parent, tm); if (err < 0) { - dev_err(&rtc->dev, "read_time: fail to read\n"); + dev_dbg(&rtc->dev, "read_time: fail to read: %d\n", + err); return err; } err = rtc_valid_tm(tm); if (err < 0) - dev_err(&rtc->dev, "read_time: rtc_time isn't valid\n"); + dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n"); } return err; } @@ -72,7 +73,11 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -ENODEV; else if (rtc->ops->set_time) err = rtc->ops->set_time(rtc->dev.parent, tm); - else if (rtc->ops->set_mmss) { + else if (rtc->ops->set_mmss64) { + time64_t secs64 = rtc_tm_to_time64(tm); + + err = rtc->ops->set_mmss64(rtc->dev.parent, secs64); + } else if (rtc->ops->set_mmss) { time64_t secs64 = rtc_tm_to_time64(tm); err = rtc->ops->set_mmss(rtc->dev.parent, secs64); } else @@ -96,6 +101,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) if (!rtc->ops) err = -ENODEV; + else if (rtc->ops->set_mmss64) + err = rtc->ops->set_mmss64(rtc->dev.parent, secs); else if (rtc->ops->set_mmss) err = rtc->ops->set_mmss(rtc->dev.parent, secs); else if (rtc->ops->read_time && rtc->ops->set_time) { diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index cfc2ef98d393..b5cbc1bf5a3e 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -881,7 +881,7 @@ static const struct rtc_class_ops rtc_ops = { .alarm_irq_enable = abb5zes3_rtc_alarm_irq_enable, }; -static struct regmap_config abb5zes3_rtc_regmap_config = { +static const struct regmap_config abb5zes3_rtc_regmap_config = { .reg_bits = 8, .val_bits = 8, }; diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index 1d0340fdb820..9b725c553058 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -43,21 +43,21 @@ /* * RTC clock functions and device struct declaration */ -static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) +static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs) { u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, AB3100_TI3, AB3100_TI4, AB3100_TI5}; unsigned char buf[6]; - u64 fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2; + u64 hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2; int err = 0; int i; - buf[0] = (fat_time) & 0xFF; - buf[1] = (fat_time >> 8) & 0xFF; - buf[2] = (fat_time >> 16) & 0xFF; - buf[3] = (fat_time >> 24) & 0xFF; - buf[4] = (fat_time >> 32) & 0xFF; - buf[5] = (fat_time >> 40) & 0xFF; + buf[0] = (hw_counter) & 0xFF; + buf[1] = (hw_counter >> 8) & 0xFF; + buf[2] = (hw_counter >> 16) & 0xFF; + buf[3] = (hw_counter >> 24) & 0xFF; + buf[4] = (hw_counter >> 32) & 0xFF; + buf[5] = (hw_counter >> 40) & 0xFF; for (i = 0; i < 6; i++) { err = abx500_set_register_interruptible(dev, 0, @@ -75,7 +75,7 @@ static int ab3100_rtc_set_mmss(struct device *dev, unsigned long secs) static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) { - unsigned long time; + time64_t time; u8 rtcval; int err; @@ -88,7 +88,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_info(dev, "clock not set (lost power)"); return -EINVAL; } else { - u64 fat_time; + u64 hw_counter; u8 buf[6]; /* Read out time registers */ @@ -98,22 +98,21 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) if (err != 0) return err; - fat_time = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) | + hw_counter = ((u64) buf[5] << 40) | ((u64) buf[4] << 32) | ((u64) buf[3] << 24) | ((u64) buf[2] << 16) | ((u64) buf[1] << 8) | (u64) buf[0]; - time = (unsigned long) (fat_time / - (u64) (AB3100_RTC_CLOCK_RATE * 2)); + time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2); } - rtc_time_to_tm(time, tm); + rtc_time64_to_tm(time, tm); return rtc_valid_tm(tm); } static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { - unsigned long time; - u64 fat_time; + time64_t time; + u64 hw_counter; u8 buf[6]; u8 rtcval; int err; @@ -134,11 +133,11 @@ static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) AB3100_AL0, buf, 4); if (err) return err; - fat_time = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) | + hw_counter = ((u64) buf[3] << 40) | ((u64) buf[2] << 32) | ((u64) buf[1] << 24) | ((u64) buf[0] << 16); - time = (unsigned long) (fat_time / (u64) (AB3100_RTC_CLOCK_RATE * 2)); + time = hw_counter / (u64) (AB3100_RTC_CLOCK_RATE * 2); - rtc_time_to_tm(time, &alarm->time); + rtc_time64_to_tm(time, &alarm->time); return rtc_valid_tm(&alarm->time); } @@ -147,17 +146,17 @@ static int ab3100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { u8 regs[] = {AB3100_AL0, AB3100_AL1, AB3100_AL2, AB3100_AL3}; unsigned char buf[4]; - unsigned long secs; - u64 fat_time; + time64_t secs; + u64 hw_counter; int err; int i; - rtc_tm_to_time(&alarm->time, &secs); - fat_time = (u64) secs * AB3100_RTC_CLOCK_RATE * 2; - buf[0] = (fat_time >> 16) & 0xFF; - buf[1] = (fat_time >> 24) & 0xFF; - buf[2] = (fat_time >> 32) & 0xFF; - buf[3] = (fat_time >> 40) & 0xFF; + secs = rtc_tm_to_time64(&alarm->time); + hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2; + buf[0] = (hw_counter >> 16) & 0xFF; + buf[1] = (hw_counter >> 24) & 0xFF; + buf[2] = (hw_counter >> 32) & 0xFF; + buf[3] = (hw_counter >> 40) & 0xFF; /* Set the alarm */ for (i = 0; i < 4; i++) { @@ -193,7 +192,7 @@ static int ab3100_rtc_irq_enable(struct device *dev, unsigned int enabled) static const struct rtc_class_ops ab3100_rtc_ops = { .read_time = ab3100_rtc_read_time, - .set_mmss = ab3100_rtc_set_mmss, + .set_mmss64 = ab3100_rtc_set_mmss, .read_alarm = ab3100_rtc_read_alarm, .set_alarm = ab3100_rtc_set_alarm, .alarm_irq_enable = ab3100_rtc_irq_enable, diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index b283a1a573b3..35efd3f75b18 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -37,9 +37,9 @@ #include "rtc-at91rm9200.h" #define at91_rtc_read(field) \ - __raw_readl(at91_rtc_regs + field) + readl_relaxed(at91_rtc_regs + field) #define at91_rtc_write(field, val) \ - __raw_writel((val), at91_rtc_regs + field) + writel_relaxed((val), at91_rtc_regs + field) #define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */ diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5b2e76159b41..a82556a0757a 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -28,6 +28,9 @@ * interrupts disabled, holding the global rtc_lock, to exclude those * other drivers and utilities on correctly configured systems. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> @@ -385,8 +388,7 @@ static bool alarm_disable_quirk; static int __init set_alarm_disable_quirk(const struct dmi_system_id *id) { alarm_disable_quirk = true; - pr_info("rtc-cmos: BIOS has alarm-disable quirk. "); - pr_info("RTC alarms disabled\n"); + pr_info("BIOS has alarm-disable quirk - RTC alarms disabled\n"); return 0; } @@ -459,23 +461,25 @@ static int cmos_procfs(struct device *dev, struct seq_file *seq) /* NOTE: at least ICH6 reports battery status using a different * (non-RTC) bit; and SQWE is ignored on many current systems. */ - return seq_printf(seq, - "periodic_IRQ\t: %s\n" - "update_IRQ\t: %s\n" - "HPET_emulated\t: %s\n" - // "square_wave\t: %s\n" - "BCD\t\t: %s\n" - "DST_enable\t: %s\n" - "periodic_freq\t: %d\n" - "batt_status\t: %s\n", - (rtc_control & RTC_PIE) ? "yes" : "no", - (rtc_control & RTC_UIE) ? "yes" : "no", - is_hpet_enabled() ? "yes" : "no", - // (rtc_control & RTC_SQWE) ? "yes" : "no", - (rtc_control & RTC_DM_BINARY) ? "no" : "yes", - (rtc_control & RTC_DST_EN) ? "yes" : "no", - cmos->rtc->irq_freq, - (valid & RTC_VRT) ? "okay" : "dead"); + seq_printf(seq, + "periodic_IRQ\t: %s\n" + "update_IRQ\t: %s\n" + "HPET_emulated\t: %s\n" + // "square_wave\t: %s\n" + "BCD\t\t: %s\n" + "DST_enable\t: %s\n" + "periodic_freq\t: %d\n" + "batt_status\t: %s\n", + (rtc_control & RTC_PIE) ? "yes" : "no", + (rtc_control & RTC_UIE) ? "yes" : "no", + is_hpet_enabled() ? "yes" : "no", + // (rtc_control & RTC_SQWE) ? "yes" : "no", + (rtc_control & RTC_DM_BINARY) ? "no" : "yes", + (rtc_control & RTC_DST_EN) ? "yes" : "no", + cmos->rtc->irq_freq, + (valid & RTC_VRT) ? "okay" : "dead"); + + return 0; } #else diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 613c43b7e9ae..1ba4371cbc2d 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/rtc.h> #include <linux/err.h> +#include <linux/delay.h> #include <linux/mfd/da9052/da9052.h> #include <linux/mfd/da9052/reg.h> @@ -23,6 +24,8 @@ #define rtc_err(rtc, fmt, ...) \ dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) +#define DA9052_GET_TIME_RETRIES 5 + struct da9052_rtc { struct rtc_device *rtc; struct da9052 *da9052; @@ -58,22 +61,43 @@ static irqreturn_t da9052_rtc_irq(int irq, void *data) static int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) { int ret; - uint8_t v[5]; + uint8_t v[2][5]; + int idx = 1; + int timeout = DA9052_GET_TIME_RETRIES; - ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v); - if (ret != 0) { + ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, &v[0][0]); + if (ret) { rtc_err(rtc, "Failed to group read ALM: %d\n", ret); return ret; } - rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; - rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; - rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; - rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; - rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; + do { + ret = da9052_group_read(rtc->da9052, + DA9052_ALARM_MI_REG, 5, &v[idx][0]); + if (ret) { + rtc_err(rtc, "Failed to group read ALM: %d\n", ret); + return ret; + } - ret = rtc_valid_tm(rtc_tm); - return ret; + if (memcmp(&v[0][0], &v[1][0], 5) == 0) { + rtc_tm->tm_year = (v[0][4] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[0][3] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[0][2] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[0][1] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[0][0] & DA9052_RTC_MIN; + + ret = rtc_valid_tm(rtc_tm); + return ret; + } + + idx = (1-idx); + msleep(20); + + } while (timeout--); + + rtc_err(rtc, "Timed out reading alarm time\n"); + + return -EIO; } static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) @@ -135,24 +159,45 @@ static int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc) static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) { struct da9052_rtc *rtc = dev_get_drvdata(dev); - uint8_t v[6]; int ret; + uint8_t v[2][6]; + int idx = 1; + int timeout = DA9052_GET_TIME_RETRIES; - ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); - if (ret < 0) { + ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, &v[0][0]); + if (ret) { rtc_err(rtc, "Failed to read RTC time : %d\n", ret); return ret; } - rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; - rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; - rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; - rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; - rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; - rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; + do { + ret = da9052_group_read(rtc->da9052, + DA9052_COUNT_S_REG, 6, &v[idx][0]); + if (ret) { + rtc_err(rtc, "Failed to read RTC time : %d\n", ret); + return ret; + } - ret = rtc_valid_tm(rtc_tm); - return ret; + if (memcmp(&v[0][0], &v[1][0], 6) == 0) { + rtc_tm->tm_year = (v[0][5] & DA9052_RTC_YEAR) + 100; + rtc_tm->tm_mon = (v[0][4] & DA9052_RTC_MONTH) - 1; + rtc_tm->tm_mday = v[0][3] & DA9052_RTC_DAY; + rtc_tm->tm_hour = v[0][2] & DA9052_RTC_HOUR; + rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN; + rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC; + + ret = rtc_valid_tm(rtc_tm); + return ret; + } + + idx = (1-idx); + msleep(20); + + } while (timeout--); + + rtc_err(rtc, "Timed out reading time\n"); + + return -EIO; } static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -161,6 +206,10 @@ static int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) uint8_t v[6]; int ret; + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ + if ((tm->tm_year < 100) || (tm->tm_year > 163)) + return -EINVAL; + rtc = dev_get_drvdata(dev); v[0] = tm->tm_sec; @@ -198,6 +247,10 @@ static int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; struct da9052_rtc *rtc = dev_get_drvdata(dev); + /* DA9052 only has 6 bits for year - to represent 2000-2063 */ + if ((tm->tm_year < 100) || (tm->tm_year > 163)) + return -EINVAL; + ret = da9052_rtc_enable_alarm(rtc, 0); if (ret < 0) return ret; @@ -256,6 +309,8 @@ static int da9052_rtc_probe(struct platform_device *pdev) return ret; } + device_init_wakeup(&pdev->dev, true); + rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &da9052_rtc_ops, THIS_MODULE); return PTR_ERR_OR_ZERO(rtc->rtc); diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c new file mode 100644 index 000000000000..8d05596a6765 --- /dev/null +++ b/drivers/rtc/rtc-digicolor.c @@ -0,0 +1,227 @@ +/* + * Real Time Clock driver for Conexant Digicolor + * + * Copyright (C) 2015 Paradox Innovation Ltd. + * + * Author: Baruch Siach <baruch@tkos.co.il> + * + * 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. + */ + +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> +#include <linux/of.h> + +#define DC_RTC_CONTROL 0x0 +#define DC_RTC_TIME 0x8 +#define DC_RTC_REFERENCE 0xc +#define DC_RTC_ALARM 0x10 +#define DC_RTC_INTFLAG_CLEAR 0x14 +#define DC_RTC_INTENABLE 0x16 + +#define DC_RTC_CMD_MASK 0xf +#define DC_RTC_GO_BUSY BIT(7) + +#define CMD_NOP 0 +#define CMD_RESET 1 +#define CMD_WRITE 3 +#define CMD_READ 4 + +#define CMD_DELAY_US (10*1000) +#define CMD_TIMEOUT_US (500*CMD_DELAY_US) + +struct dc_rtc { + struct rtc_device *rtc_dev; + void __iomem *regs; +}; + +static int dc_rtc_cmds(struct dc_rtc *rtc, const u8 *cmds, int len) +{ + u8 val; + int i, ret; + + for (i = 0; i < len; i++) { + writeb_relaxed((cmds[i] & DC_RTC_CMD_MASK) | DC_RTC_GO_BUSY, + rtc->regs + DC_RTC_CONTROL); + ret = readb_relaxed_poll_timeout( + rtc->regs + DC_RTC_CONTROL, val, + !(val & DC_RTC_GO_BUSY), CMD_DELAY_US, CMD_TIMEOUT_US); + if (ret < 0) + return ret; + } + + return 0; +} + +static int dc_rtc_read(struct dc_rtc *rtc, unsigned long *val) +{ + static const u8 read_cmds[] = {CMD_READ, CMD_NOP}; + u32 reference, time1, time2; + int ret; + + ret = dc_rtc_cmds(rtc, read_cmds, ARRAY_SIZE(read_cmds)); + if (ret < 0) + return ret; + + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + time1 = readl_relaxed(rtc->regs + DC_RTC_TIME); + /* Read twice to ensure consistency */ + while (1) { + time2 = readl_relaxed(rtc->regs + DC_RTC_TIME); + if (time1 == time2) + break; + time1 = time2; + } + + *val = reference + time1; + return 0; +} + +static int dc_rtc_write(struct dc_rtc *rtc, u32 val) +{ + static const u8 write_cmds[] = {CMD_WRITE, CMD_NOP, CMD_RESET, CMD_NOP}; + + writel_relaxed(val, rtc->regs + DC_RTC_REFERENCE); + return dc_rtc_cmds(rtc, write_cmds, ARRAY_SIZE(write_cmds)); +} + +static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + unsigned long now; + int ret; + + ret = dc_rtc_read(rtc, &now); + if (ret < 0) + return ret; + rtc_time64_to_tm(now, tm); + + return 0; +} + +static int dc_rtc_set_mmss(struct device *dev, unsigned long secs) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + + return dc_rtc_write(rtc, secs); +} + +static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + u32 alarm_reg, reference; + unsigned long now; + int ret; + + alarm_reg = readl_relaxed(rtc->regs + DC_RTC_ALARM); + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + rtc_time64_to_tm(reference + alarm_reg, &alarm->time); + + ret = dc_rtc_read(rtc, &now); + if (ret < 0) + return ret; + + alarm->pending = alarm_reg + reference > now; + alarm->enabled = readl_relaxed(rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static int dc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + time64_t alarm_time; + u32 reference; + + alarm_time = rtc_tm_to_time64(&alarm->time); + + reference = readl_relaxed(rtc->regs + DC_RTC_REFERENCE); + writel_relaxed(alarm_time - reference, rtc->regs + DC_RTC_ALARM); + + writeb_relaxed(!!alarm->enabled, rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct dc_rtc *rtc = dev_get_drvdata(dev); + + writeb_relaxed(!!enabled, rtc->regs + DC_RTC_INTENABLE); + + return 0; +} + +static struct rtc_class_ops dc_rtc_ops = { + .read_time = dc_rtc_read_time, + .set_mmss = dc_rtc_set_mmss, + .read_alarm = dc_rtc_read_alarm, + .set_alarm = dc_rtc_set_alarm, + .alarm_irq_enable = dc_rtc_alarm_irq_enable, +}; + +static irqreturn_t dc_rtc_irq(int irq, void *dev_id) +{ + struct dc_rtc *rtc = dev_id; + + writeb_relaxed(1, rtc->regs + DC_RTC_INTFLAG_CLEAR); + rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); + + return IRQ_HANDLED; +} + +static int __init dc_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct dc_rtc *rtc; + int irq, ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rtc->regs)) + return PTR_ERR(rtc->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + ret = devm_request_irq(&pdev->dev, irq, dc_rtc_irq, 0, pdev->name, rtc); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, rtc); + rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, + &dc_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + + return 0; +} + +static const struct of_device_id dc_dt_ids[] = { + { .compatible = "cnxt,cx92755-rtc" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, dc_dt_ids); + +static struct platform_driver dc_rtc_driver = { + .driver = { + .name = "digicolor_rtc", + .of_match_table = of_match_ptr(dc_dt_ids), + }, +}; +module_platform_driver_probe(dc_rtc_driver, dc_rtc_probe); + +MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); +MODULE_DESCRIPTION("Conexant Digicolor Realtime Clock Driver (RTC)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 129add77065d..12b07158a366 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -434,9 +434,9 @@ static int ds1305_proc(struct device *dev, struct seq_file *seq) } done: - return seq_printf(seq, - "trickle_charge\t: %s%s\n", - diodes, resistors); + seq_printf(seq, "trickle_charge\t: %s%s\n", diodes, resistors); + + return 0; } #else diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 8605fde394b2..167783fa7ac1 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -18,6 +18,8 @@ * "Sending and receiving", using SMBus level communication is preferred. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -406,7 +408,7 @@ static int ds1374_wdt_settimeout(unsigned int timeout) /* Set new watchdog time */ ret = ds1374_write_rtc(save_client, timeout, DS1374_REG_WDALM0, 3); if (ret) { - pr_info("rtc-ds1374 - couldn't set new watchdog time\n"); + pr_info("couldn't set new watchdog time\n"); goto out; } @@ -539,12 +541,12 @@ static long ds1374_wdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (options & WDIOS_DISABLECARD) { - pr_info("rtc-ds1374: disable watchdog\n"); + pr_info("disable watchdog\n"); ds1374_wdt_disable(); } if (options & WDIOS_ENABLECARD) { - pr_info("rtc-ds1374: enable watchdog\n"); + pr_info("enable watchdog\n"); ds1374_wdt_settimeout(wdt_margin); ds1374_wdt_ping(); } diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 803869c7d7c2..818a3635a8c8 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -16,6 +16,8 @@ * published by the Free Software Foundation. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/bcd.h> #include <linux/delay.h> #include <linux/io.h> @@ -799,7 +801,7 @@ ds1685_rtc_proc(struct device *dev, struct seq_file *seq) struct platform_device *pdev = to_platform_device(dev); struct ds1685_priv *rtc = platform_get_drvdata(pdev); u8 ctrla, ctrlb, ctrlc, ctrld, ctrl4a, ctrl4b, ssn[8]; - char *model = '\0'; + char *model; #ifdef CONFIG_RTC_DS1685_PROC_REGS char bits[NUM_REGS][(NUM_BITS * NUM_SPACES) + NUM_BITS + 1]; #endif @@ -2139,7 +2141,6 @@ ds1685_rtc_remove(struct platform_device *pdev) static struct platform_driver ds1685_rtc_driver = { .driver = { .name = "rtc-ds1685", - .owner = THIS_MODULE, }, .probe = ds1685_rtc_probe, .remove = ds1685_rtc_remove, @@ -2175,7 +2176,7 @@ module_exit(ds1685_rtc_exit); * ds1685_rtc_poweroff - uses the RTC chip to power the system off. * @pdev: pointer to platform_device structure. */ -extern void __noreturn +void __noreturn ds1685_rtc_poweroff(struct platform_device *pdev) { u8 ctrla, ctrl4a, ctrl4b; @@ -2183,7 +2184,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev) /* Check for valid RTC data, else, spin forever. */ if (unlikely(!pdev)) { - pr_emerg("rtc-ds1685: platform device data not available, spinning forever ...\n"); + pr_emerg("platform device data not available, spinning forever ...\n"); unreachable(); } else { /* Get the rtc data. */ diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index adaf06c41479..7e48e532214f 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -15,6 +15,8 @@ * "Sending and receiving", using SMBus level communication is preferred. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/module.h> #include <linux/interrupt.h> @@ -373,8 +375,8 @@ static void ds3232_work(struct work_struct *work) if (stat & DS3232_REG_SR_A1F) { control = i2c_smbus_read_byte_data(client, DS3232_REG_CR); if (control < 0) { - pr_warn("Read DS3232 Control Register error." - "Disable IRQ%d.\n", client->irq); + pr_warn("Read Control Register error - Disable IRQ%d\n", + client->irq); } else { /* disable alarm1 interrupt */ control &= ~(DS3232_REG_CR_A1IE); diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c index b40fbe332af4..1a7f1d1bc174 100644 --- a/drivers/rtc/rtc-efi-platform.c +++ b/drivers/rtc/rtc-efi-platform.c @@ -8,6 +8,9 @@ * Copyright (C) 1999-2000 VA Linux Systems * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com> */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> diff --git a/drivers/rtc/rtc-em3027.c b/drivers/rtc/rtc-em3027.c index fccf36699245..4f4930a2004c 100644 --- a/drivers/rtc/rtc-em3027.c +++ b/drivers/rtc/rtc-em3027.c @@ -15,6 +15,7 @@ #include <linux/rtc.h> #include <linux/bcd.h> #include <linux/module.h> +#include <linux/of.h> /* Registers */ #define EM3027_REG_ON_OFF_CTRL 0x00 @@ -135,10 +136,20 @@ static struct i2c_device_id em3027_id[] = { { "em3027", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, em3027_id); + +#ifdef CONFIG_OF +static const struct of_device_id em3027_of_match[] = { + { .compatible = "emmicro,em3027", }, + {} +}; +MODULE_DEVICE_TABLE(of, em3027_of_match); +#endif static struct i2c_driver em3027_driver = { .driver = { .name = "rtc-em3027", + .of_match_table = of_match_ptr(em3027_of_match), }, .probe = &em3027_probe, .id_table = em3027_id, diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index ae7c2ba440cf..af4f85a66b39 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -213,7 +213,7 @@ static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm) /* get a report with all values through requesting one value */ sensor_hub_input_attr_get_raw_value(time_state->common_attributes.hsdev, HID_USAGE_SENSOR_TIME, hid_time_addresses[0], - time_state->info[0].report_id); + time_state->info[0].report_id, SENSOR_HUB_SYNC); /* wait for all values (event) */ ret = wait_for_completion_killable_timeout( &time_state->comp_last_time, HZ*6); diff --git a/drivers/rtc/rtc-hym8563.c b/drivers/rtc/rtc-hym8563.c index b936bb4096b5..0f710e98538f 100644 --- a/drivers/rtc/rtc-hym8563.c +++ b/drivers/rtc/rtc-hym8563.c @@ -66,7 +66,7 @@ #define HYM8563_ALM_BIT_DISABLE BIT(7) #define HYM8563_CLKOUT 0x0d -#define HYM8563_CLKOUT_DISABLE BIT(7) +#define HYM8563_CLKOUT_ENABLE BIT(7) #define HYM8563_CLKOUT_32768 0 #define HYM8563_CLKOUT_1024 1 #define HYM8563_CLKOUT_32 2 @@ -309,7 +309,7 @@ static unsigned long hym8563_clkout_recalc_rate(struct clk_hw *hw, struct i2c_client *client = hym8563->client; int ret = i2c_smbus_read_byte_data(client, HYM8563_CLKOUT); - if (ret < 0 || ret & HYM8563_CLKOUT_DISABLE) + if (ret < 0) return 0; ret &= HYM8563_CLKOUT_MASK; @@ -360,9 +360,9 @@ static int hym8563_clkout_control(struct clk_hw *hw, bool enable) return ret; if (enable) - ret &= ~HYM8563_CLKOUT_DISABLE; + ret |= HYM8563_CLKOUT_ENABLE; else - ret |= HYM8563_CLKOUT_DISABLE; + ret &= ~HYM8563_CLKOUT_ENABLE; return i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, ret); } @@ -386,7 +386,7 @@ static int hym8563_clkout_is_prepared(struct clk_hw *hw) if (ret < 0) return ret; - return !(ret & HYM8563_CLKOUT_DISABLE); + return !!(ret & HYM8563_CLKOUT_ENABLE); } static const struct clk_ops hym8563_clkout_ops = { @@ -407,7 +407,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563) int ret; ret = i2c_smbus_write_byte_data(client, HYM8563_CLKOUT, - HYM8563_CLKOUT_DISABLE); + 0); if (ret < 0) return ERR_PTR(ret); diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 7ff7427c2e6a..a82937e2f824 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -13,6 +13,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/bcd.h> #include <linux/i2c.h> #include <linux/init.h> @@ -513,12 +515,12 @@ static int wdt_ioctl(struct file *file, unsigned int cmd, return -EFAULT; if (rv & WDIOS_DISABLECARD) { - pr_info("rtc-m41t80: disable watchdog\n"); + pr_info("disable watchdog\n"); wdt_disable(); } if (rv & WDIOS_ENABLECARD) { - pr_info("rtc-m41t80: enable watchdog\n"); + pr_info("enable watchdog\n"); wdt_ping(); } diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 9d71328e59b9..7632a87784c3 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -12,6 +12,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/slab.h> #include <linux/rtc.h> #include <linux/delay.h> @@ -103,8 +105,8 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_warn("%s: MAX77686 RTC cannot handle the year %d." - "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", + 1900 + tm->tm_year); return -EINVAL; } return 0; diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index 67fbe559d535..9e02bcda0c09 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c @@ -12,6 +12,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/slab.h> #include <linux/rtc.h> #include <linux/delay.h> @@ -107,8 +109,8 @@ static int max8997_rtc_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_warn("%s: MAX8997 RTC cannot handle the year %d." - "Assume it's 2000.\n", __func__, 1900 + tm->tm_year); + pr_warn("RTC cannot handle the year %d. Assume it's 2000.\n", + 1900 + tm->tm_year); return -EINVAL; } return 0; @@ -424,7 +426,7 @@ static void max8997_rtc_enable_smpl(struct max8997_rtc_info *info, bool enable) val = 0; max8997_read_reg(info->rtc, MAX8997_RTC_WTSR_SMPL, &val); - pr_info("%s: WTSR_SMPL(0x%02x)\n", __func__, val); + pr_info("WTSR_SMPL(0x%02x)\n", val); } static int max8997_rtc_init_reg(struct max8997_rtc_info *info) diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 5bce904b7ee6..32df1d812367 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -83,20 +83,19 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) return ret; } while (days1 != days2); - rtc_time_to_tm(days1 * SEC_PER_DAY + seconds, tm); + rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm); return rtc_valid_tm(tm); } -static int mc13xxx_rtc_set_mmss(struct device *dev, unsigned long secs) +static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; - seconds = secs % SEC_PER_DAY; - days = secs / SEC_PER_DAY; + days = div_s64_rem(secs, SEC_PER_DAY, &seconds); mc13xxx_lock(priv->mc13xxx); @@ -159,7 +158,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned seconds, days; - unsigned long s1970; + time64_t s1970; int enabled, pending; int ret; @@ -189,10 +188,10 @@ out: alarm->enabled = enabled; alarm->pending = pending; - s1970 = days * SEC_PER_DAY + seconds; + s1970 = (time64_t)days * SEC_PER_DAY + seconds; - rtc_time_to_tm(s1970, &alarm->time); - dev_dbg(dev, "%s: %lu\n", __func__, s1970); + rtc_time64_to_tm(s1970, &alarm->time); + dev_dbg(dev, "%s: %lld\n", __func__, (long long)s1970); return 0; } @@ -200,8 +199,8 @@ out: static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); - unsigned long s1970; - unsigned seconds, days; + time64_t s1970; + u32 seconds, days; int ret; mc13xxx_lock(priv->mc13xxx); @@ -215,20 +214,17 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (unlikely(ret)) goto out; - ret = rtc_tm_to_time(&alarm->time, &s1970); - if (unlikely(ret)) - goto out; + s1970 = rtc_tm_to_time64(&alarm->time); - dev_dbg(dev, "%s: o%2.s %lu\n", __func__, alarm->enabled ? "n" : "ff", - s1970); + dev_dbg(dev, "%s: o%2.s %lld\n", __func__, alarm->enabled ? "n" : "ff", + (long long)s1970); ret = mc13xxx_rtc_irq_enable_unlocked(dev, alarm->enabled, MC13XXX_IRQ_TODA); if (unlikely(ret)) goto out; - seconds = s1970 % SEC_PER_DAY; - days = s1970 / SEC_PER_DAY; + days = div_s64_rem(s1970, SEC_PER_DAY, &seconds); ret = mc13xxx_reg_write(priv->mc13xxx, MC13XXX_RTCDAYA, days); if (unlikely(ret)) @@ -268,7 +264,7 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev) static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_time = mc13xxx_rtc_read_time, - .set_mmss = mc13xxx_rtc_set_mmss, + .set_mmss64 = mc13xxx_rtc_set_mmss, .read_alarm = mc13xxx_rtc_read_alarm, .set_alarm = mc13xxx_rtc_set_alarm, .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 3a6fd3a8a2ec..548ea6f6f384 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -277,13 +277,15 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq) valid = vrtc_cmos_read(RTC_VALID); spin_unlock_irq(&rtc_lock); - return seq_printf(seq, - "periodic_IRQ\t: %s\n" - "alarm\t\t: %s\n" - "BCD\t\t: no\n" - "periodic_freq\t: daily (not adjustable)\n", - (rtc_control & RTC_PIE) ? "on" : "off", - (rtc_control & RTC_AIE) ? "on" : "off"); + seq_printf(seq, + "periodic_IRQ\t: %s\n" + "alarm\t\t: %s\n" + "BCD\t\t: no\n" + "periodic_freq\t: daily (not adjustable)\n", + (rtc_control & RTC_PIE) ? "on" : "off", + (rtc_control & RTC_AIE) ? "on" : "off"); + + return 0; } #else diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index 9bf877bdf836..c1c5c4e3b3b4 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -7,6 +7,8 @@ * Copyright (C) 1993 Hamish Macdonald */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/delay.h> #include <linux/io.h> #include <linux/kernel.h> @@ -111,7 +113,7 @@ static void msm6242_lock(struct msm6242_priv *priv) } if (!cnt) - pr_warn("msm6242: timed out waiting for RTC (0x%x)\n", + pr_warn("timed out waiting for RTC (0x%x)\n", msm6242_read(priv, MSM6242_CD)); } diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 3c3f8d10ab43..09d422b9f7f7 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -106,7 +106,7 @@ static inline int is_imx1_rtc(struct rtc_plat_data *data) * This function is used to obtain the RTC time or the alarm value in * second. */ -static u32 get_alarm_or_time(struct device *dev, int time_alarm) +static time64_t get_alarm_or_time(struct device *dev, int time_alarm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); @@ -129,29 +129,28 @@ static u32 get_alarm_or_time(struct device *dev, int time_alarm) hr = hr_min >> 8; min = hr_min & 0xff; - return (((day * 24 + hr) * 60) + min) * 60 + sec; + return ((((time64_t)day * 24 + hr) * 60) + min) * 60 + sec; } /* * This function sets the RTC alarm value or the time value. */ -static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time) +static void set_alarm_or_time(struct device *dev, int time_alarm, time64_t time) { - u32 day, hr, min, sec, temp; + u32 tod, day, hr, min, sec, temp; struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - day = time / 86400; - time -= day * 86400; + day = div_s64_rem(time, 86400, &tod); /* time is within a day now */ - hr = time / 3600; - time -= hr * 3600; + hr = tod / 3600; + tod -= hr * 3600; /* time is within an hour now */ - min = time / 60; - sec = time - min * 60; + min = tod / 60; + sec = tod - min * 60; temp = (hr << 8) + min; @@ -173,29 +172,18 @@ static void set_alarm_or_time(struct device *dev, int time_alarm, u32 time) * This function updates the RTC alarm registers and then clears all the * interrupt status bits. */ -static int rtc_update_alarm(struct device *dev, struct rtc_time *alrm) +static void rtc_update_alarm(struct device *dev, struct rtc_time *alrm) { - struct rtc_time alarm_tm, now_tm; - unsigned long now, time; + time64_t time; struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - now = get_alarm_or_time(dev, MXC_RTC_TIME); - rtc_time_to_tm(now, &now_tm); - alarm_tm.tm_year = now_tm.tm_year; - alarm_tm.tm_mon = now_tm.tm_mon; - alarm_tm.tm_mday = now_tm.tm_mday; - alarm_tm.tm_hour = alrm->tm_hour; - alarm_tm.tm_min = alrm->tm_min; - alarm_tm.tm_sec = alrm->tm_sec; - rtc_tm_to_time(&alarm_tm, &time); + time = rtc_tm_to_time64(alrm); /* clear all the interrupt status bits */ writew(readw(ioaddr + RTC_RTCISR), ioaddr + RTC_RTCISR); set_alarm_or_time(dev, MXC_RTC_ALARM, time); - - return 0; } static void mxc_rtc_irq_enable(struct device *dev, unsigned int bit, @@ -283,14 +271,14 @@ static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) { - u32 val; + time64_t val; /* Avoid roll-over from reading the different registers */ do { val = get_alarm_or_time(dev, MXC_RTC_TIME); } while (val != get_alarm_or_time(dev, MXC_RTC_TIME)); - rtc_time_to_tm(val, tm); + rtc_time64_to_tm(val, tm); return 0; } @@ -298,7 +286,7 @@ static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) /* * This function sets the internal RTC time based on tm in Gregorian date. */ -static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) +static int mxc_rtc_set_mmss(struct device *dev, time64_t time) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); @@ -309,9 +297,9 @@ static int mxc_rtc_set_mmss(struct device *dev, unsigned long time) if (is_imx1_rtc(pdata)) { struct rtc_time tm; - rtc_time_to_tm(time, &tm); + rtc_time64_to_tm(time, &tm); tm.tm_year = 70; - rtc_tm_to_time(&tm, &time); + time = rtc_tm_to_time64(&tm); } /* Avoid roll-over from reading the different registers */ @@ -333,7 +321,7 @@ static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - rtc_time_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time); + rtc_time64_to_tm(get_alarm_or_time(dev, MXC_RTC_ALARM), &alrm->time); alrm->pending = ((readw(ioaddr + RTC_RTCISR) & RTC_ALM_BIT)) ? 1 : 0; return 0; @@ -346,11 +334,8 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct platform_device *pdev = to_platform_device(dev); struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - int ret; - ret = rtc_update_alarm(dev, &alrm->time); - if (ret) - return ret; + rtc_update_alarm(dev, &alrm->time); memcpy(&pdata->g_rtc_alarm, &alrm->time, sizeof(struct rtc_time)); mxc_rtc_irq_enable(dev, RTC_ALM_BIT, alrm->enabled); @@ -362,7 +347,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static struct rtc_class_ops mxc_rtc_ops = { .release = mxc_rtc_release, .read_time = mxc_rtc_read_time, - .set_mmss = mxc_rtc_set_mmss, + .set_mmss64 = mxc_rtc_set_mmss, .read_alarm = mxc_rtc_read_alarm, .set_alarm = mxc_rtc_set_alarm, .alarm_irq_enable = mxc_rtc_alarm_irq_enable, diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 8e5851aa4369..8b6355ffaff9 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -118,12 +118,15 @@ #define KICK0_VALUE 0x83e70b13 #define KICK1_VALUE 0x95a4f1e0 +struct omap_rtc; + struct omap_rtc_device_type { bool has_32kclk_en; - bool has_kicker; bool has_irqwakeen; bool has_pmic_mode; bool has_power_up_reset; + void (*lock)(struct omap_rtc *rtc); + void (*unlock)(struct omap_rtc *rtc); }; struct omap_rtc { @@ -156,6 +159,26 @@ static inline void rtc_writel(struct omap_rtc *rtc, unsigned int reg, u32 val) writel(val, rtc->base + reg); } +static void am3352_rtc_unlock(struct omap_rtc *rtc) +{ + rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); + rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); +} + +static void am3352_rtc_lock(struct omap_rtc *rtc) +{ + rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc_writel(rtc, OMAP_RTC_KICK1_REG, 0); +} + +static void default_rtc_unlock(struct omap_rtc *rtc) +{ +} + +static void default_rtc_lock(struct omap_rtc *rtc) +{ +} + /* * We rely on the rtc framework to handle locking (rtc->ops_lock), * so the only other requirement is that register accesses which @@ -186,7 +209,9 @@ static irqreturn_t rtc_irq(int irq, void *dev_id) /* alarm irq? */ if (irq_data & OMAP_RTC_STATUS_ALARM) { + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM); + rtc->type->lock(rtc); events |= RTC_IRQF | RTC_AF; } @@ -218,9 +243,11 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) irqwake_reg &= ~OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN; } rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); if (rtc->type->has_irqwakeen) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); + rtc->type->lock(rtc); local_irq_enable(); return 0; @@ -293,12 +320,14 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) local_irq_disable(); rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_YEARS_REG, tm->tm_year); rtc_write(rtc, OMAP_RTC_MONTHS_REG, tm->tm_mon); rtc_write(rtc, OMAP_RTC_DAYS_REG, tm->tm_mday); rtc_write(rtc, OMAP_RTC_HOURS_REG, tm->tm_hour); rtc_write(rtc, OMAP_RTC_MINUTES_REG, tm->tm_min); rtc_write(rtc, OMAP_RTC_SECONDS_REG, tm->tm_sec); + rtc->type->lock(rtc); local_irq_enable(); @@ -341,6 +370,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) local_irq_disable(); rtc_wait_not_busy(rtc); + rtc->type->unlock(rtc); rtc_write(rtc, OMAP_RTC_ALARM_YEARS_REG, alm->time.tm_year); rtc_write(rtc, OMAP_RTC_ALARM_MONTHS_REG, alm->time.tm_mon); rtc_write(rtc, OMAP_RTC_ALARM_DAYS_REG, alm->time.tm_mday); @@ -362,6 +392,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, reg); if (rtc->type->has_irqwakeen) rtc_write(rtc, OMAP_RTC_IRQWAKEEN, irqwake_reg); + rtc->type->lock(rtc); local_irq_enable(); @@ -391,6 +422,7 @@ static void omap_rtc_power_off(void) unsigned long now; u32 val; + rtc->type->unlock(rtc); /* enable pmic_power_en control */ val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN); @@ -423,6 +455,7 @@ static void omap_rtc_power_off(void) val = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); rtc_writel(rtc, OMAP_RTC_INTERRUPTS_REG, val | OMAP_RTC_INTERRUPTS_IT_ALARM2); + rtc->type->lock(rtc); /* * Wait for alarm to trigger (within two seconds) and external PMIC to @@ -442,17 +475,21 @@ static struct rtc_class_ops omap_rtc_ops = { static const struct omap_rtc_device_type omap_rtc_default_type = { .has_power_up_reset = true, + .lock = default_rtc_lock, + .unlock = default_rtc_unlock, }; static const struct omap_rtc_device_type omap_rtc_am3352_type = { .has_32kclk_en = true, - .has_kicker = true, .has_irqwakeen = true, .has_pmic_mode = true, + .lock = am3352_rtc_lock, + .unlock = am3352_rtc_unlock, }; static const struct omap_rtc_device_type omap_rtc_da830_type = { - .has_kicker = true, + .lock = am3352_rtc_lock, + .unlock = am3352_rtc_unlock, }; static const struct platform_device_id omap_rtc_id_table[] = { @@ -484,7 +521,7 @@ static const struct of_device_id omap_rtc_of_match[] = { }; MODULE_DEVICE_TABLE(of, omap_rtc_of_match); -static int __init omap_rtc_probe(struct platform_device *pdev) +static int omap_rtc_probe(struct platform_device *pdev) { struct omap_rtc *rtc; struct resource *res; @@ -527,10 +564,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - if (rtc->type->has_kicker) { - rtc_writel(rtc, OMAP_RTC_KICK0_REG, KICK0_VALUE); - rtc_writel(rtc, OMAP_RTC_KICK1_REG, KICK1_VALUE); - } + rtc->type->unlock(rtc); /* * disable interrupts @@ -593,6 +627,8 @@ static int __init omap_rtc_probe(struct platform_device *pdev) if (reg != new_ctrl) rtc_write(rtc, OMAP_RTC_CTRL_REG, new_ctrl); + rtc->type->lock(rtc); + device_init_wakeup(&pdev->dev, true); rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, @@ -626,8 +662,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) err: device_init_wakeup(&pdev->dev, false); - if (rtc->type->has_kicker) - rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc->type->lock(rtc); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -646,11 +681,11 @@ static int __exit omap_rtc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); + rtc->type->unlock(rtc); /* leave rtc running, but disable irqs */ rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); - if (rtc->type->has_kicker) - rtc_writel(rtc, OMAP_RTC_KICK0_REG, 0); + rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(&pdev->dev); @@ -666,6 +701,7 @@ static int omap_rtc_suspend(struct device *dev) rtc->interrupts_reg = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); + rtc->type->unlock(rtc); /* * FIXME: the RTC alarm is not currently acting as a wakeup event * source on some platforms, and in fact this enable() call is just @@ -675,6 +711,7 @@ static int omap_rtc_suspend(struct device *dev) enable_irq_wake(rtc->irq_alarm); else rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, 0); + rtc->type->lock(rtc); /* Disable the clock/module */ pm_runtime_put_sync(dev); @@ -689,10 +726,12 @@ static int omap_rtc_resume(struct device *dev) /* Enable the clock/module so that we can access the registers */ pm_runtime_get_sync(dev); + rtc->type->unlock(rtc); if (device_may_wakeup(dev)) disable_irq_wake(rtc->irq_alarm); else rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, rtc->interrupts_reg); + rtc->type->lock(rtc); return 0; } @@ -709,12 +748,15 @@ static void omap_rtc_shutdown(struct platform_device *pdev) * Keep the ALARM interrupt enabled to allow the system to power up on * alarm events. */ + rtc->type->unlock(rtc); mask = rtc_read(rtc, OMAP_RTC_INTERRUPTS_REG); mask &= OMAP_RTC_INTERRUPTS_IT_ALARM; rtc_write(rtc, OMAP_RTC_INTERRUPTS_REG, mask); + rtc->type->lock(rtc); } static struct platform_driver omap_rtc_driver = { + .probe = omap_rtc_probe, .remove = __exit_p(omap_rtc_remove), .shutdown = omap_rtc_shutdown, .driver = { @@ -725,7 +767,7 @@ static struct platform_driver omap_rtc_driver = { .id_table = omap_rtc_id_table, }; -module_platform_driver_probe(omap_rtc_driver, omap_rtc_probe); +module_platform_driver(omap_rtc_driver); MODULE_ALIAS("platform:omap_rtc"); MODULE_AUTHOR("George G. Davis (and others)"); diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index 95f652165fe9..7061dcae2b09 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -16,8 +16,9 @@ * along with this program. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRVNAME "rtc-opal" -#define pr_fmt(fmt) DRVNAME ": " fmt #include <linux/module.h> #include <linux/err.h> diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 96fb32e7d6f8..0ba7e59929be 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -246,7 +246,6 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm) static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) { struct pcf8563 *pcf8563 = i2c_get_clientdata(client); - int err; unsigned char buf[9]; dev_dbg(&client->dev, "%s: secs=%d, mins=%d, hours=%d, " @@ -272,12 +271,8 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm) buf[PCF8563_REG_DW] = tm->tm_wday & 0x07; - err = pcf8563_write_block_data(client, PCF8563_REG_SC, + return pcf8563_write_block_data(client, PCF8563_REG_SC, 9 - PCF8563_REG_SC, buf + PCF8563_REG_SC); - if (err) - return err; - - return 0; } #ifdef CONFIG_RTC_INTF_DEV diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index f4cf6851fae9..76cbad7a99d3 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -39,7 +39,6 @@ struct s3c_rtc { void __iomem *base; struct clk *rtc_clk; struct clk *rtc_src_clk; - bool enabled; struct s3c_rtc_data *data; @@ -67,26 +66,25 @@ struct s3c_rtc_data { void (*disable) (struct s3c_rtc *info); }; -static void s3c_rtc_alarm_clk_enable(struct s3c_rtc *info, bool enable) +static void s3c_rtc_enable_clk(struct s3c_rtc *info) { unsigned long irq_flags; spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); - if (enable) { - if (!info->enabled) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - info->enabled = true; - } - } else { - if (info->enabled) { - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - info->enabled = false; - } - } + clk_enable(info->rtc_clk); + if (info->data->needs_src_clk) + clk_enable(info->rtc_src_clk); + spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); +} + +static void s3c_rtc_disable_clk(struct s3c_rtc *info) +{ + unsigned long irq_flags; + + spin_lock_irqsave(&info->alarm_clk_lock, irq_flags); + if (info->data->needs_src_clk) + clk_disable(info->rtc_src_clk); + clk_disable(info->rtc_clk); spin_unlock_irqrestore(&info->alarm_clk_lock, irq_flags); } @@ -119,20 +117,16 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled) dev_dbg(info->dev, "%s: aie=%d\n", __func__, enabled); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); + tmp = readb(info->base + S3C2410_RTCALM) & ~S3C2410_RTCALM_ALMEN; if (enabled) tmp |= S3C2410_RTCALM_ALMEN; writeb(tmp, info->base + S3C2410_RTCALM); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - s3c_rtc_alarm_clk_enable(info, enabled); + s3c_rtc_disable_clk(info); return 0; } @@ -143,18 +137,12 @@ static int s3c_rtc_setfreq(struct s3c_rtc *info, int freq) if (!is_power_of_2(freq)) return -EINVAL; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); spin_lock_irq(&info->pie_lock); if (info->data->set_freq) info->data->set_freq(info, freq); spin_unlock_irq(&info->pie_lock); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); return 0; } @@ -165,9 +153,7 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) struct s3c_rtc *info = dev_get_drvdata(dev); unsigned int have_retried = 0; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); retry_get_time: rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN); @@ -194,6 +180,8 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon); rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year); + s3c_rtc_disable_clk(info); + rtc_tm->tm_year += 100; dev_dbg(dev, "read time %04d.%02d.%02d %02d:%02d:%02d\n", @@ -202,10 +190,6 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_mon -= 1; - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return rtc_valid_tm(rtc_tm); } @@ -225,9 +209,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) return -EINVAL; } - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); writeb(bin2bcd(tm->tm_sec), info->base + S3C2410_RTCSEC); writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN); @@ -236,9 +218,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON); writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; } @@ -249,9 +229,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *alm_tm = &alrm->time; unsigned int alm_en; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); alm_tm->tm_sec = readb(info->base + S3C2410_ALMSEC); alm_tm->tm_min = readb(info->base + S3C2410_ALMMIN); @@ -262,6 +240,8 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) alm_en = readb(info->base + S3C2410_RTCALM); + s3c_rtc_disable_clk(info); + alrm->enabled = (alm_en & S3C2410_RTCALM_ALMEN) ? 1 : 0; dev_dbg(dev, "read alarm %d, %04d.%02d.%02d %02d:%02d:%02d\n", @@ -269,9 +249,7 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) 1900 + alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday, alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec); - /* decode the alarm enable field */ - if (alm_en & S3C2410_RTCALM_SECEN) alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec); else @@ -304,10 +282,6 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) else alm_tm->tm_year = -1; - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } @@ -317,15 +291,13 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) struct rtc_time *tm = &alrm->time; unsigned int alrm_en; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - dev_dbg(dev, "s3c_rtc_setalarm: %d, %04d.%02d.%02d %02d:%02d:%02d\n", alrm->enabled, 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + s3c_rtc_enable_clk(info); + alrm_en = readb(info->base + S3C2410_RTCALM) & S3C2410_RTCALM_ALMEN; writeb(0x00, info->base + S3C2410_RTCALM); @@ -348,11 +320,9 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) writeb(alrm_en, info->base + S3C2410_RTCALM); - s3c_rtc_setaie(dev, alrm->enabled); + s3c_rtc_disable_clk(info); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_setaie(dev, alrm->enabled); return 0; } @@ -361,16 +331,12 @@ static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); if (info->data->enable_tick) info->data->enable_tick(info, seq); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; } @@ -388,10 +354,6 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) { unsigned int con, tmp; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); /* re-enable the device, and check it is ok */ if ((con & S3C2410_RTCCON_RTCEN) == 0) { @@ -417,20 +379,12 @@ static void s3c24xx_rtc_enable(struct s3c_rtc *info) writew(tmp & ~S3C2410_RTCCON_CLKRST, info->base + S3C2410_RTCCON); } - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static void s3c24xx_rtc_disable(struct s3c_rtc *info) { unsigned int con; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); con &= ~S3C2410_RTCCON_RTCEN; writew(con, info->base + S3C2410_RTCCON); @@ -438,28 +392,16 @@ static void s3c24xx_rtc_disable(struct s3c_rtc *info) con = readb(info->base + S3C2410_TICNT); con &= ~S3C2410_TICNT_ENABLE; writeb(con, info->base + S3C2410_TICNT); - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static void s3c6410_rtc_disable(struct s3c_rtc *info) { unsigned int con; - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - con = readw(info->base + S3C2410_RTCCON); con &= ~S3C64XX_RTCCON_TICEN; con &= ~S3C2410_RTCCON_RTCEN; writew(con, info->base + S3C2410_RTCCON); - - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); } static int s3c_rtc_remove(struct platform_device *pdev) @@ -554,6 +496,20 @@ static int s3c_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); + /* Check RTC Time */ + if (s3c_rtc_gettime(&pdev->dev, &rtc_tm)) { + rtc_tm.tm_year = 100; + rtc_tm.tm_mon = 0; + rtc_tm.tm_mday = 1; + rtc_tm.tm_hour = 0; + rtc_tm.tm_min = 0; + rtc_tm.tm_sec = 0; + + s3c_rtc_settime(&pdev->dev, &rtc_tm); + + dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); + } + /* register RTC and exit */ info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops, THIS_MODULE); @@ -577,36 +533,21 @@ static int s3c_rtc_probe(struct platform_device *pdev) goto err_nortc; } - /* Check RTC Time */ - s3c_rtc_gettime(&pdev->dev, &rtc_tm); - - if (rtc_valid_tm(&rtc_tm)) { - rtc_tm.tm_year = 100; - rtc_tm.tm_mon = 0; - rtc_tm.tm_mday = 1; - rtc_tm.tm_hour = 0; - rtc_tm.tm_min = 0; - rtc_tm.tm_sec = 0; - - s3c_rtc_settime(&pdev->dev, &rtc_tm); - - dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n"); - } - if (info->data->select_tick_clk) info->data->select_tick_clk(info); s3c_rtc_setfreq(info, 1); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); + s3c_rtc_disable_clk(info); return 0; err_nortc: if (info->data->disable) info->data->disable(info); + + if (info->data->needs_src_clk) + clk_disable_unprepare(info->rtc_src_clk); clk_disable_unprepare(info->rtc_clk); return ret; @@ -618,9 +559,7 @@ static int s3c_rtc_suspend(struct device *dev) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); + s3c_rtc_enable_clk(info); /* save TICNT for anyone using periodic interrupts */ if (info->data->save_tick_cnt) @@ -636,10 +575,6 @@ static int s3c_rtc_suspend(struct device *dev) dev_err(dev, "enable_irq_wake failed\n"); } - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } @@ -647,25 +582,19 @@ static int s3c_rtc_resume(struct device *dev) { struct s3c_rtc *info = dev_get_drvdata(dev); - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); - if (info->data->enable) info->data->enable(info); if (info->data->restore_tick_cnt) info->data->restore_tick_cnt(info); + s3c_rtc_disable_clk(info); + if (device_may_wakeup(dev) && info->wake_en) { disable_irq_wake(info->irq_alarm); info->wake_en = false; } - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - return 0; } #endif @@ -673,29 +602,13 @@ static SIMPLE_DEV_PM_OPS(s3c_rtc_pm_ops, s3c_rtc_suspend, s3c_rtc_resume); static void s3c24xx_rtc_irq(struct s3c_rtc *info, int mask) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - - s3c_rtc_alarm_clk_enable(info, false); } static void s3c6410_rtc_irq(struct s3c_rtc *info, int mask) { - clk_enable(info->rtc_clk); - if (info->data->needs_src_clk) - clk_enable(info->rtc_src_clk); rtc_update_irq(info->rtc, 1, RTC_AF | RTC_IRQF); writeb(mask, info->base + S3C2410_INTP); - if (info->data->needs_src_clk) - clk_disable(info->rtc_src_clk); - clk_disable(info->rtc_clk); - - s3c_rtc_alarm_clk_enable(info, false); } static void s3c2410_rtc_setfreq(struct s3c_rtc *info, int freq) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 89ac1d5083c6..8c70d785ba73 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/module.h> #include <linux/i2c.h> #include <linux/bcd.h> @@ -48,8 +50,6 @@ struct s5m_rtc_reg_config { unsigned int alarm0; /* First register for alarm 1, seconds */ unsigned int alarm1; - /* SMPL/WTSR register */ - unsigned int smpl_wtsr; /* * Register for update flag (UDR). Typically setting UDR field to 1 * will enable update of time or alarm register. Then it will be @@ -67,7 +67,6 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = { .ctrl = S5M_ALARM1_CONF, .alarm0 = S5M_ALARM0_SEC, .alarm1 = S5M_ALARM1_SEC, - .smpl_wtsr = S5M_WTSR_SMPL_CNTL, .rtc_udr_update = S5M_RTC_UDR_CON, .rtc_udr_mask = S5M_RTC_UDR_MASK, }; @@ -82,7 +81,6 @@ static const struct s5m_rtc_reg_config s2mps_rtc_regs = { .ctrl = S2MPS_RTC_CTRL, .alarm0 = S2MPS_ALARM0_SEC, .alarm1 = S2MPS_ALARM1_SEC, - .smpl_wtsr = S2MPS_WTSR_SMPL_CNTL, .rtc_udr_update = S2MPS_RTC_UDR_CON, .rtc_udr_mask = S2MPS_RTC_WUDR_MASK, }; @@ -94,9 +92,8 @@ struct s5m_rtc_info { struct regmap *regmap; struct rtc_device *rtc_dev; int irq; - int device_type; + enum sec_device_type device_type; int rtc_24hr_mode; - bool wtsr_smpl; const struct s5m_rtc_reg_config *regs; }; @@ -151,7 +148,7 @@ static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data) data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0; if (tm->tm_year < 100) { - pr_err("s5m8767 RTC cannot handle the year %d.\n", + pr_err("RTC cannot handle the year %d\n", 1900 + tm->tm_year); return -EINVAL; } else { @@ -192,6 +189,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info, val &= S5M_ALARM0_STATUS; break; case S2MPS14X: + case S2MPS13X: ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2, &val); val &= S2MPS_ALARM0_STATUS; @@ -257,6 +255,9 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) case S2MPS14X: data |= S2MPS_RTC_RUDR_MASK; break; + case S2MPS13X: + data |= S2MPS13_RTC_AUDR_MASK; + break; default: return -EINVAL; } @@ -270,6 +271,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info) ret = s5m8767_wait_for_udr_update(info); + /* On S2MPS13 the AUDR is not auto-cleared */ + if (info->device_type == S2MPS13X) + regmap_update_bits(info->regmap, info->regs->rtc_udr_update, + S2MPS13_RTC_AUDR_MASK, 0); + return ret; } @@ -311,7 +317,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) u8 data[info->regs->regs_count]; int ret; - if (info->device_type == S2MPS14X) { + if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) { ret = regmap_update_bits(info->regmap, info->regs->rtc_udr_update, S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK); @@ -334,6 +340,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode); break; @@ -360,6 +367,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) break; case S5M8767X: case S2MPS14X: + case S2MPS13X: ret = s5m8767_tm_to_data(tm, data); break; default: @@ -407,6 +415,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode); alrm->enabled = 0; for (i = 0; i < info->regs->regs_count; i++) { @@ -455,6 +464,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) case S5M8767X: case S2MPS14X: + case S2MPS13X: for (i = 0; i < info->regs->regs_count; i++) data[i] &= ~ALARM_ENABLE_MASK; @@ -499,6 +509,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) case S5M8767X: case S2MPS14X: + case S2MPS13X: data[RTC_SEC] |= ALARM_ENABLE_MASK; data[RTC_MIN] |= ALARM_ENABLE_MASK; data[RTC_HOUR] |= ALARM_ENABLE_MASK; @@ -538,6 +549,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) case S5M8767X: case S2MPS14X: + case S2MPS13X: s5m8767_tm_to_data(&alrm->time, data); break; @@ -597,28 +609,6 @@ static const struct rtc_class_ops s5m_rtc_ops = { .alarm_irq_enable = s5m_rtc_alarm_irq_enable, }; -static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable) -{ - int ret; - ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr, - WTSR_ENABLE_MASK, - enable ? WTSR_ENABLE_MASK : 0); - if (ret < 0) - dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n", - __func__, ret); -} - -static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable) -{ - int ret; - ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr, - SMPL_ENABLE_MASK, - enable ? SMPL_ENABLE_MASK : 0); - if (ret < 0) - dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n", - __func__, ret); -} - static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) { u8 data[2]; @@ -642,6 +632,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info) break; case S2MPS14X: + case S2MPS13X: data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); ret = regmap_write(info->regmap, info->regs->ctrl, data[0]); break; @@ -677,8 +668,9 @@ static int s5m_rtc_probe(struct platform_device *pdev) if (!info) return -ENOMEM; - switch (pdata->device_type) { + switch (platform_get_device_id(pdev)->driver_data) { case S2MPS14X: + case S2MPS13X: regmap_cfg = &s2mps14_rtc_regmap_config; info->regs = &s2mps_rtc_regs; alarm_irq = S2MPS14_IRQ_RTCA0; @@ -694,7 +686,9 @@ static int s5m_rtc_probe(struct platform_device *pdev) alarm_irq = S5M8767_IRQ_RTCA1; break; default: - dev_err(&pdev->dev, "Device type is not supported by RTC driver\n"); + dev_err(&pdev->dev, + "Device type %lu is not supported by RTC driver\n", + platform_get_device_id(pdev)->driver_data); return -ENODEV; } @@ -714,8 +708,7 @@ static int s5m_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->s5m87xx = s5m87xx; - info->device_type = s5m87xx->device_type; - info->wtsr_smpl = s5m87xx->wtsr_smpl; + info->device_type = platform_get_device_id(pdev)->driver_data; if (s5m87xx->irq_data) { info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq); @@ -731,11 +724,6 @@ static int s5m_rtc_probe(struct platform_device *pdev) ret = s5m8767_rtc_init_reg(info); - if (info->wtsr_smpl) { - s5m_rtc_enable_wtsr(info, true); - s5m_rtc_enable_smpl(info, true); - } - device_init_wakeup(&pdev->dev, 1); info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc", @@ -768,36 +756,10 @@ err: return ret; } -static void s5m_rtc_shutdown(struct platform_device *pdev) -{ - struct s5m_rtc_info *info = platform_get_drvdata(pdev); - int i; - unsigned int val = 0; - if (info->wtsr_smpl) { - for (i = 0; i < 3; i++) { - s5m_rtc_enable_wtsr(info, false); - regmap_read(info->regmap, info->regs->smpl_wtsr, &val); - pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val); - if (val & WTSR_ENABLE_MASK) - pr_emerg("%s: fail to disable WTSR\n", - __func__); - else { - pr_info("%s: success to disable WTSR\n", - __func__); - break; - } - } - } - /* Disable SMPL when power off */ - s5m_rtc_enable_smpl(info, false); -} - static int s5m_rtc_remove(struct platform_device *pdev) { struct s5m_rtc_info *info = platform_get_drvdata(pdev); - /* Perform also all shutdown steps when removing */ - s5m_rtc_shutdown(pdev); i2c_unregister_device(info->i2c); return 0; @@ -831,6 +793,7 @@ static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume); static const struct platform_device_id s5m_rtc_id[] = { { "s5m-rtc", S5M8767X }, + { "s2mps13-rtc", S2MPS13X }, { "s2mps14-rtc", S2MPS14X }, { }, }; @@ -842,7 +805,6 @@ static struct platform_driver s5m_rtc_driver = { }, .probe = s5m_rtc_probe, .remove = s5m_rtc_remove, - .shutdown = s5m_rtc_shutdown, .id_table = s5m_rtc_id, }; diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index 2939cdcb2688..eb09eddf39b8 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -42,6 +42,8 @@ #define STMP3XXX_RTC_STAT 0x10 #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 #define STMP3XXX_RTC_STAT_RTC_PRESENT 0x80000000 +#define STMP3XXX_RTC_STAT_XTAL32000_PRESENT 0x10000000 +#define STMP3XXX_RTC_STAT_XTAL32768_PRESENT 0x08000000 #define STMP3XXX_RTC_SECONDS 0x30 @@ -52,9 +54,13 @@ #define STMP3XXX_RTC_PERSISTENT0 0x60 #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN 0x00000002 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 -#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 +#define STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE (1 << 0) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN (1 << 1) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_EN (1 << 2) +#define STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP (1 << 4) +#define STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP (1 << 5) +#define STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ (1 << 6) +#define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE (1 << 7) #define STMP3XXX_RTC_PERSISTENT1 0x70 /* missing bitmask in headers */ @@ -248,6 +254,9 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) { struct stmp3xxx_rtc_data *rtc_data; struct resource *r; + u32 rtc_stat; + u32 pers0_set, pers0_clr; + u32 crystalfreq = 0; int err; rtc_data = devm_kzalloc(&pdev->dev, sizeof(*rtc_data), GFP_KERNEL); @@ -268,8 +277,8 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) rtc_data->irq_alarm = platform_get_irq(pdev, 0); - if (!(readl(STMP3XXX_RTC_STAT + rtc_data->io) & - STMP3XXX_RTC_STAT_RTC_PRESENT)) { + rtc_stat = readl(rtc_data->io + STMP3XXX_RTC_STAT); + if (!(rtc_stat & STMP3XXX_RTC_STAT_RTC_PRESENT)) { dev_err(&pdev->dev, "no device onboard\n"); return -ENODEV; } @@ -282,9 +291,54 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) return err; } + /* + * Obviously the rtc needs a clock input to be able to run. + * This clock can be provided by an external 32k crystal. If that one is + * missing XTAL must not be disabled in suspend which consumes a + * lot of power. Normally the presence and exact frequency (supported + * are 32000 Hz and 32768 Hz) is detectable from fuses, but as reality + * proves these fuses are not blown correctly on all machines, so the + * frequency can be overridden in the device tree. + */ + if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32000_PRESENT) + crystalfreq = 32000; + else if (rtc_stat & STMP3XXX_RTC_STAT_XTAL32768_PRESENT) + crystalfreq = 32768; + + of_property_read_u32(pdev->dev.of_node, "stmp,crystal-freq", + &crystalfreq); + + switch (crystalfreq) { + case 32000: + /* keep 32kHz crystal running in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ | + STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; + break; + case 32768: + /* keep 32.768kHz crystal running in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_XTAL32_FREQ; + break; + default: + dev_warn(&pdev->dev, + "invalid crystal-freq specified in device-tree. Assuming no crystal\n"); + /* fall-through */ + case 0: + /* keep XTAL on in low-power mode */ + pers0_set = STMP3XXX_RTC_PERSISTENT0_XTAL24MHZ_PWRUP; + pers0_clr = STMP3XXX_RTC_PERSISTENT0_XTAL32KHZ_PWRUP | + STMP3XXX_RTC_PERSISTENT0_CLOCKSOURCE; + } + + writel(pers0_set, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_SET); + writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN | STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN | - STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE, + STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE | pers0_clr, rtc_data->io + STMP3XXX_RTC_PERSISTENT0_CLR); writel(STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN | diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index d948277057d8..60232bd366ef 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -261,7 +261,9 @@ static int tegra_rtc_proc(struct device *dev, struct seq_file *seq) if (!dev || !dev->driver) return 0; - return seq_printf(seq, "name\t\t: %s\n", dev_name(dev)); + seq_printf(seq, "name\t\t: %s\n", dev_name(dev)); + + return 0; } static irqreturn_t tegra_rtc_irq_handler(int irq, void *data) diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 8f86fa91de1a..3a2da4c892d6 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -13,6 +13,10 @@ #include <linux/rtc.h> #include <linux/platform_device.h> +static int test_mmss64; +module_param(test_mmss64, int, 0644); +MODULE_PARM_DESC(test_mmss64, "Test struct rtc_class_ops.set_mmss64()."); + static struct platform_device *test0 = NULL, *test1 = NULL; static int test_rtc_read_alarm(struct device *dev, @@ -30,7 +34,13 @@ static int test_rtc_set_alarm(struct device *dev, static int test_rtc_read_time(struct device *dev, struct rtc_time *tm) { - rtc_time_to_tm(get_seconds(), tm); + rtc_time64_to_tm(ktime_get_real_seconds(), tm); + return 0; +} + +static int test_rtc_set_mmss64(struct device *dev, time64_t secs) +{ + dev_info(dev, "%s, secs = %lld\n", __func__, (long long)secs); return 0; } @@ -55,7 +65,7 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) return 0; } -static const struct rtc_class_ops test_rtc_ops = { +static struct rtc_class_ops test_rtc_ops = { .proc = test_rtc_proc, .read_time = test_rtc_read_time, .read_alarm = test_rtc_read_alarm, @@ -101,6 +111,11 @@ static int test_probe(struct platform_device *plat_dev) int err; struct rtc_device *rtc; + if (test_mmss64) { + test_rtc_ops.set_mmss64 = test_rtc_set_mmss64; + test_rtc_ops.set_mmss = NULL; + } + rtc = devm_rtc_device_register(&plat_dev->dev, "test", &test_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 5baea3f54926..2dc787dc06c1 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -18,6 +18,8 @@ * 2 of the License, or (at your option) any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/errno.h> #include <linux/init.h> @@ -145,8 +147,7 @@ static int twl_rtc_read_u8(u8 *data, u8 reg) ret = twl_i2c_read_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); if (ret < 0) - pr_err("twl_rtc: Could not read TWL" - "register %X - error %d\n", reg, ret); + pr_err("Could not read TWL register %X - error %d\n", reg, ret); return ret; } @@ -159,8 +160,8 @@ static int twl_rtc_write_u8(u8 data, u8 reg) ret = twl_i2c_write_u8(TWL_MODULE_RTC, data, (rtc_reg_map[reg])); if (ret < 0) - pr_err("twl_rtc: Could not write TWL" - "register %X - error %d\n", reg, ret); + pr_err("Could not write TWL register %X - error %d\n", + reg, ret); return ret; } diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index b1de58e0b3d0..5638b7ba8b06 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -22,6 +22,7 @@ #include <linux/rtc.h> #include <linux/delay.h> #include <linux/module.h> +#include <linux/bitops.h> #define DRV_VERSION "1.0.8" @@ -366,8 +367,7 @@ static int x1205_get_atrim(struct i2c_client *client, int *trim) * perform sign extension. The formula is * Catr = (atr * 0.25pF) + 11.00pF. */ - if (atr & 0x20) - atr |= 0xC0; + atr = sign_extend32(atr, 5); dev_dbg(&client->dev, "%s: raw atr=%x (%d)\n", __func__, atr, atr); diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index eb71872d0361..7728d5e32bf4 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -11,7 +11,7 @@ * rtc_set_ntp_time - Save NTP synchronized time to the RTC * @now: Current time of day * - * Replacement for the NTP platform function update_persistent_clock + * Replacement for the NTP platform function update_persistent_clock64 * that stores time for later retrieval by rtc_hctosys. * * Returns 0 on successful RTC update, -ENODEV if a RTC update is not @@ -35,7 +35,10 @@ int rtc_set_ntp_time(struct timespec64 now) if (rtc) { /* rtc_hctosys exclusively uses UTC, so we call set_time here, * not set_mmss. */ - if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss)) + if (rtc->ops && + (rtc->ops->set_time || + rtc->ops->set_mmss64 || + rtc->ops->set_mmss)) err = rtc_set_time(rtc, &tm); rtc_class_close(rtc); } |