diff options
67 files changed, 1400 insertions, 1510 deletions
diff --git a/Documentation/devicetree/bindings/rtc/nxp,pcf85063.txt b/Documentation/devicetree/bindings/rtc/nxp,pcf85063.txt index d3e380ad712d..627bb533eff7 100644 --- a/Documentation/devicetree/bindings/rtc/nxp,pcf85063.txt +++ b/Documentation/devicetree/bindings/rtc/nxp,pcf85063.txt @@ -1,7 +1,11 @@ * NXP PCF85063 Real Time Clock Required properties: -- compatible: Should contain "nxp,pcf85063". +- compatible: Should one of contain: + "nxp,pcf85063", + "nxp,pcf85063a", + "nxp,pcf85063tp", + "microcrystal,rv8263" - reg: I2C address for chip. Optional property: diff --git a/Documentation/devicetree/bindings/rtc/rtc-aspeed.txt b/Documentation/devicetree/bindings/rtc/rtc-aspeed.txt new file mode 100644 index 000000000000..2e956b3dc276 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-aspeed.txt @@ -0,0 +1,22 @@ +ASPEED BMC RTC +============== + +Required properties: + - compatible: should be one of the following + * aspeed,ast2400-rtc for the ast2400 + * aspeed,ast2500-rtc for the ast2500 + * aspeed,ast2600-rtc for the ast2600 + + - reg: physical base address of the controller and length of memory mapped + region + + - interrupts: The interrupt number + +Example: + + rtc@1e781000 { + compatible = "aspeed,ast2400-rtc"; + reg = <0x1e781000 0x18>; + interrupts = <22>; + status = "disabled"; + }; diff --git a/Documentation/devicetree/bindings/rtc/rtc.txt b/Documentation/devicetree/bindings/rtc/rtc.txt index f4687c68c08c..a97fc6a9a75e 100644 --- a/Documentation/devicetree/bindings/rtc/rtc.txt +++ b/Documentation/devicetree/bindings/rtc/rtc.txt @@ -69,3 +69,4 @@ ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC sii,s35390a 2-wire CMOS real-time clock whwave,sd3078 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC +xircom,x1205 Xircom X1205 I2C RTC diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index f933c06bff4f..7b8e156dbf38 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -439,6 +439,7 @@ config RTC_DRV_PCF8523 config RTC_DRV_PCF85063 tristate "NXP PCF85063" + select REGMAP_I2C help If you say yes here you get support for the PCF85063 RTC chip @@ -447,7 +448,6 @@ config RTC_DRV_PCF85063 config RTC_DRV_PCF85363 tristate "NXP PCF85363" - depends on I2C select REGMAP_I2C help If you say yes here you get support for the PCF85363 RTC chip. @@ -602,7 +602,6 @@ config RTC_DRV_FM3130 config RTC_DRV_RX8010 tristate "Epson RX8010SJ" - depends on I2C help If you say yes here you get support for the Epson RX8010SJ RTC chip. @@ -1432,7 +1431,7 @@ config RTC_DRV_AT91RM9200 config RTC_DRV_AT91SAM9 tristate "AT91SAM9 RTT as RTC" depends on ARCH_AT91 || COMPILE_TEST - depends on HAS_IOMEM + depends on OF && HAS_IOMEM select MFD_SYSCON help Some AT91SAM9 SoCs provide an RTT (Real Time Timer) block which @@ -1841,6 +1840,17 @@ config RTC_DRV_RTD119X If you say yes here, you get support for the RTD1295 SoC Real Time Clock. +config RTC_DRV_ASPEED + tristate "ASPEED RTC" + depends on OF + depends on ARCH_ASPEED || COMPILE_TEST + help + If you say yes here you get support for the ASPEED BMC SoC real time + clocks. + + This driver can also be built as a module, if so, the module + will be called "rtc-aspeed". + comment "HID Sensor RTC drivers" config RTC_DRV_HID_SENSOR_TIME @@ -1857,7 +1867,8 @@ config RTC_DRV_HID_SENSOR_TIME config RTC_DRV_GOLDFISH tristate "Goldfish Real Time Clock" - depends on MIPS && (GOLDFISH || COMPILE_TEST) + depends on OF && HAS_IOMEM + depends on GOLDFISH || COMPILE_TEST help Say yes to enable RTC driver for the Goldfish based virtual platform. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index fe3962496685..9d997faa2c26 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o +obj-$(CONFIG_RTC_DRV_ASPEED) += rtc-aspeed.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index ac93b76f2b11..0f492b0940b3 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, base class * @@ -5,11 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * class skeleton from drivers/hwmon/hwmon.c - * - * 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. -*/ + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -23,13 +20,13 @@ #include "rtc-core.h" - static DEFINE_IDA(rtc_ida); struct class *rtc_class; static void rtc_device_release(struct device *dev) { struct rtc_device *rtc = to_rtc_device(dev); + ida_simple_remove(&rtc_ida, rtc->id); kfree(rtc); } @@ -47,7 +44,6 @@ int rtc_hctosys_ret = -ENODEV; static struct timespec64 old_rtc, old_system, old_delta; - static int rtc_suspend(struct device *dev) { struct rtc_device *rtc = to_rtc_device(dev); @@ -71,7 +67,6 @@ static int rtc_suspend(struct device *dev) ktime_get_real_ts64(&old_system); old_rtc.tv_sec = rtc_tm_to_time64(&tm); - /* * To avoid drift caused by repeated suspend/resumes, * which each can add ~1 second drift error, @@ -83,7 +78,7 @@ static int rtc_suspend(struct device *dev) if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) { /* * if delta_delta is too large, assume time correction - * has occured and set old_delta to the current delta. + * has occurred and set old_delta to the current delta. */ old_delta = delta; } else { @@ -136,7 +131,7 @@ static int rtc_resume(struct device *dev) * to keep things accurate. */ sleep_time = timespec64_sub(sleep_time, - timespec64_sub(new_system, old_system)); + timespec64_sub(new_system, old_system)); if (sleep_time.tv_sec >= 0) timekeeping_inject_sleeptime64(&sleep_time); @@ -397,9 +392,9 @@ EXPORT_SYMBOL_GPL(__rtc_register_device); * rtc_register_device instead */ struct rtc_device *devm_rtc_device_register(struct device *dev, - const char *name, - const struct rtc_class_ops *ops, - struct module *owner) + const char *name, + const struct rtc_class_ops *ops, + struct module *owner) { struct rtc_device *rtc; int err; diff --git a/drivers/rtc/dev.c b/drivers/rtc/dev.c index 1d006ef4bb57..84feb2565abd 100644 --- a/drivers/rtc/dev.c +++ b/drivers/rtc/dev.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, dev interface * @@ -5,11 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * based on arch/arm/common/rtctime.c - * - * 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. -*/ + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -60,7 +57,7 @@ static void rtc_uie_task(struct work_struct *work) } else if (rtc->oldsecs != tm.tm_sec) { num = (tm.tm_sec + 60 - rtc->oldsecs) % 60; rtc->oldsecs = tm.tm_sec; - rtc->uie_timer.expires = jiffies + HZ - (HZ/10); + rtc->uie_timer.expires = jiffies + HZ - (HZ / 10); rtc->uie_timer_active = 1; rtc->uie_task_active = 0; add_timer(&rtc->uie_timer); @@ -71,6 +68,7 @@ static void rtc_uie_task(struct work_struct *work) if (num) rtc_handle_legacy_irq(rtc, num, RTC_UF); } + static void rtc_uie_timer(struct timer_list *t) { struct rtc_device *rtc = from_timer(rtc, t, uie_timer); @@ -202,14 +200,14 @@ static __poll_t rtc_dev_poll(struct file *file, poll_table *wait) } static long rtc_dev_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { int err = 0; struct rtc_device *rtc = file->private_data; const struct rtc_class_ops *ops = rtc->ops; struct rtc_time tm; struct rtc_wkalrm alarm; - void __user *uarg = (void __user *) arg; + void __user *uarg = (void __user *)arg; err = mutex_lock_interruptible(&rtc->ops_lock); if (err) @@ -233,7 +231,7 @@ static long rtc_dev_ioctl(struct file *file, case RTC_PIE_ON: if (rtc->irq_freq > rtc->max_user_freq && - !capable(CAP_SYS_RESOURCE)) + !capable(CAP_SYS_RESOURCE)) err = -EACCES; break; } @@ -390,8 +388,9 @@ static long rtc_dev_ioctl(struct file *file, err = ops->ioctl(rtc->dev.parent, cmd, arg); if (err == -ENOIOCTLCMD) err = -ENOTTY; - } else + } else { err = -ENOTTY; + } break; } @@ -403,6 +402,7 @@ done: static int rtc_dev_fasync(int fd, struct file *file, int on) { struct rtc_device *rtc = file->private_data; + return fasync_helper(fd, file, on, &rtc->async_queue); } diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index ff2092a0d38c..a74d0d890600 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, initialize system time on startup * * Copyright (C) 2005 Tower Technologies * Author: Alessandro Zummo <a.zummo@towertech.it> - * - * 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. -*/ + */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -33,7 +30,7 @@ static int __init rtc_hctosys(void) }; struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - if (rtc == NULL) { + if (!rtc) { pr_info("unable to open rtc device (%s)\n", CONFIG_RTC_HCTOSYS_DEVICE); goto err_open; @@ -44,7 +41,6 @@ static int __init rtc_hctosys(void) dev_err(rtc->dev.parent, "hctosys: unable to read the hardware clock\n"); goto err_read; - } tv64.tv_sec = rtc_tm_to_time64(&tm); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 98d9c87b0d1b..4124f4dd376b 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, interface functions * @@ -5,11 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * based on arch/arm/common/rtctime.c - * - * 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. -*/ + */ #include <linux/rtc.h> #include <linux/sched.h> @@ -87,11 +84,12 @@ static int rtc_valid_range(struct rtc_device *rtc, struct rtc_time *tm) static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) { int err; - if (!rtc->ops) + + if (!rtc->ops) { err = -ENODEV; - else if (!rtc->ops->read_time) + } else if (!rtc->ops->read_time) { err = -EINVAL; - else { + } else { memset(tm, 0, sizeof(struct rtc_time)); err = rtc->ops->read_time(rtc->dev.parent, tm); if (err < 0) { @@ -147,14 +145,7 @@ 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_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 + else err = -EINVAL; pm_stay_awake(rtc->dev.parent); @@ -167,7 +158,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) } EXPORT_SYMBOL_GPL(rtc_set_time); -static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +static int rtc_read_alarm_internal(struct rtc_device *rtc, + struct rtc_wkalrm *alarm) { int err; @@ -175,11 +167,11 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al if (err) return err; - if (rtc->ops == NULL) + if (!rtc->ops) { err = -ENODEV; - else if (!rtc->ops->read_alarm) + } else if (!rtc->ops->read_alarm) { err = -EINVAL; - else { + } else { alarm->enabled = 0; alarm->pending = 0; alarm->time.tm_sec = -1; @@ -207,7 +199,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) int first_time = 1; time64_t t_now, t_alm; enum { none, day, month, year } missing = none; - unsigned days; + unsigned int days; /* The lower level RTC driver may return -1 in some fields, * creating invalid alarm->time values, for reasons like: @@ -276,10 +268,10 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) return err; /* note that tm_sec is a "don't care" value here: */ - } while ( before.tm_min != now.tm_min - || before.tm_hour != now.tm_hour - || before.tm_mon != now.tm_mon - || before.tm_year != now.tm_year); + } while (before.tm_min != now.tm_min || + before.tm_hour != now.tm_hour || + before.tm_mon != now.tm_mon || + before.tm_year != now.tm_year); /* Fill in the missing alarm fields using the timestamp; we * know there's at least one since alarm->time is invalid. @@ -296,7 +288,7 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) alarm->time.tm_mday = now.tm_mday; missing = day; } - if ((unsigned)alarm->time.tm_mon >= 12) { + if ((unsigned int)alarm->time.tm_mon >= 12) { alarm->time.tm_mon = now.tm_mon; if (missing == none) missing = month; @@ -321,7 +313,6 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) goto done; switch (missing) { - /* 24 hour rollover ... if it's now 10am Monday, an alarm that * that will trigger at 5am will do so at 5am Tuesday, which * could also be in the next month or year. This is a common @@ -341,14 +332,14 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) case month: dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month"); do { - if (alarm->time.tm_mon < 11) + if (alarm->time.tm_mon < 11) { alarm->time.tm_mon++; - else { + } else { alarm->time.tm_mon = 0; alarm->time.tm_year++; } days = rtc_month_days(alarm->time.tm_mon, - alarm->time.tm_year); + alarm->time.tm_year); } while (days < alarm->time.tm_mday); break; @@ -357,8 +348,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); do { alarm->time.tm_year++; - } while (!is_leap_year(alarm->time.tm_year + 1900) - && rtc_valid_tm(&alarm->time) != 0); + } while (!is_leap_year(alarm->time.tm_year + 1900) && + rtc_valid_tm(&alarm->time) != 0); break; default: @@ -369,7 +360,8 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) done: if (err) - dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", &alarm->time); + dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", + &alarm->time); return err; } @@ -381,11 +373,11 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; - if (rtc->ops == NULL) + if (!rtc->ops) { err = -ENODEV; - else if (!rtc->ops->read_alarm) + } else if (!rtc->ops->read_alarm) { err = -EINVAL; - else { + } else { memset(alarm, 0, sizeof(struct rtc_wkalrm)); alarm->enabled = rtc->aie_timer.enabled; alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); @@ -494,7 +486,6 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) /* Alarm has to be enabled & in the future for us to enqueue it */ if (alarm->enabled && (rtc_tm_to_ktime(now) < rtc->aie_timer.node.expires)) { - rtc->aie_timer.enabled = 1; timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); trace_rtc_timer_enqueue(&rtc->aie_timer); @@ -506,7 +497,9 @@ EXPORT_SYMBOL_GPL(rtc_initialize_alarm); int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) { - int err = mutex_lock_interruptible(&rtc->ops_lock); + int err; + + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -535,7 +528,9 @@ EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) { - int err = mutex_lock_interruptible(&rtc->ops_lock); + int err; + + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -564,27 +559,25 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); rtc->uie_rtctimer.period = ktime_set(1, 0); err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); - } else + } else { rtc_timer_remove(rtc, &rtc->uie_rtctimer); + } out: mutex_unlock(&rtc->ops_lock); #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL /* - * Enable emulation if the driver did not provide - * the update_irq_enable function pointer or if returned - * -EINVAL to signal that it has been configured without - * interrupts or that are not available at the moment. + * Enable emulation if the driver returned -EINVAL to signal that it has + * been configured without interrupts or they are not available at the + * moment. */ if (err == -EINVAL) err = rtc_dev_update_irq_enable_emul(rtc, enabled); #endif return err; - } EXPORT_SYMBOL_GPL(rtc_update_irq_enable); - /** * rtc_handle_legacy_irq - AIE, UIE and PIE event hook * @rtc: pointer to the rtc device @@ -599,14 +592,13 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) /* mark one irq of the appropriate mode */ spin_lock_irqsave(&rtc->irq_lock, flags); - rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); + rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF | mode); spin_unlock_irqrestore(&rtc->irq_lock, flags); wake_up_interruptible(&rtc->irq_queue); kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); } - /** * rtc_aie_update_irq - AIE mode rtctimer hook * @rtc: pointer to the rtc_device @@ -618,7 +610,6 @@ void rtc_aie_update_irq(struct rtc_device *rtc) rtc_handle_legacy_irq(rtc, 1, RTC_AF); } - /** * rtc_uie_update_irq - UIE mode rtctimer hook * @rtc: pointer to the rtc_device @@ -630,7 +621,6 @@ void rtc_uie_update_irq(struct rtc_device *rtc) rtc_handle_legacy_irq(rtc, 1, RTC_UF); } - /** * rtc_pie_update_irq - PIE mode hrtimer hook * @timer: pointer to the pie mode hrtimer @@ -644,6 +634,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) struct rtc_device *rtc; ktime_t period; int count; + rtc = container_of(timer, struct rtc_device, pie_timer); period = NSEC_PER_SEC / rtc->irq_freq; @@ -662,7 +653,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) * Context: any */ void rtc_update_irq(struct rtc_device *rtc, - unsigned long num, unsigned long events) + unsigned long num, unsigned long events) { if (IS_ERR_OR_NULL(rtc)) return; @@ -811,6 +802,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) if (!next || ktime_before(timer->node.expires, next->expires)) { struct rtc_wkalrm alarm; int err; + alarm.time = rtc_ktime_to_tm(timer->node.expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -851,12 +843,14 @@ static void rtc_alarm_disable(struct rtc_device *rtc) static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) { struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); + timerqueue_del(&rtc->timerqueue, &timer->node); trace_rtc_timer_dequeue(timer); timer->enabled = 0; if (next == &timer->node) { struct rtc_wkalrm alarm; int err; + next = timerqueue_getnext(&rtc->timerqueue); if (!next) { rtc_alarm_disable(rtc); @@ -929,9 +923,9 @@ again: alarm.enabled = 1; reprogram: err = __rtc_set_alarm(rtc, &alarm); - if (err == -ETIME) + if (err == -ETIME) { goto again; - else if (err) { + } else if (err) { if (retry-- > 0) goto reprogram; @@ -942,14 +936,14 @@ reprogram: dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err); goto again; } - } else + } else { rtc_alarm_disable(rtc); + } pm_relax(rtc->dev.parent); mutex_unlock(&rtc->ops_lock); } - /* rtc_timer_init - Initializes an rtc_timer * @timer: timer to be intiialized * @f: function pointer to be called when timer fires @@ -975,9 +969,10 @@ void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r), * Kernel interface to set an rtc_timer */ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, - ktime_t expires, ktime_t period) + ktime_t expires, ktime_t period) { int ret = 0; + mutex_lock(&rtc->ops_lock); if (timer->enabled) rtc_timer_remove(rtc, timer); diff --git a/drivers/rtc/lib.c b/drivers/rtc/lib.c index 9714cb3d1e29..23284580df97 100644 --- a/drivers/rtc/lib.c +++ b/drivers/rtc/lib.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * rtc and date/time utility functions * @@ -5,11 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * based on arch/arm/common/rtctime.c and other bits - * - * 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. -*/ + */ #include <linux/export.h> #include <linux/rtc.h> @@ -25,7 +22,7 @@ static const unsigned short rtc_ydays[2][13] = { { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; -#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) +#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) /* * The number of days in the month. @@ -41,11 +38,10 @@ EXPORT_SYMBOL(rtc_month_days); */ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) { - return rtc_ydays[is_leap_year(year)][month] + day-1; + return rtc_ydays[is_leap_year(year)][month] + day - 1; } EXPORT_SYMBOL(rtc_year_days); - /* * rtc_time64_to_tm - Converts time64_t to rtc_time. * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. @@ -97,13 +93,15 @@ EXPORT_SYMBOL(rtc_time64_to_tm); */ int rtc_valid_tm(struct rtc_time *tm) { - if (tm->tm_year < 70 - || ((unsigned)tm->tm_mon) >= 12 - || tm->tm_mday < 1 - || tm->tm_mday > rtc_month_days(tm->tm_mon, ((unsigned)tm->tm_year + 1900)) - || ((unsigned)tm->tm_hour) >= 24 - || ((unsigned)tm->tm_min) >= 60 - || ((unsigned)tm->tm_sec) >= 60) + if (tm->tm_year < 70 || + tm->tm_year > (INT_MAX - 1900) || + ((unsigned int)tm->tm_mon) >= 12 || + tm->tm_mday < 1 || + tm->tm_mday > rtc_month_days(tm->tm_mon, + ((unsigned int)tm->tm_year + 1900)) || + ((unsigned int)tm->tm_hour) >= 24 || + ((unsigned int)tm->tm_min) >= 60 || + ((unsigned int)tm->tm_sec) >= 60) return -EINVAL; return 0; @@ -116,7 +114,7 @@ EXPORT_SYMBOL(rtc_valid_tm); */ time64_t rtc_tm_to_time64(struct rtc_time *tm) { - return mktime64(((unsigned)tm->tm_year + 1900), tm->tm_mon + 1, + return mktime64(((unsigned int)tm->tm_year + 1900), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } EXPORT_SYMBOL(rtc_tm_to_time64); diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index dce518d5e50e..4312096c7738 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, nvmem interface * * Copyright (C) 2017 Alexandre Belloni - * - * 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. */ #include <linux/err.h> @@ -46,7 +43,7 @@ static int rtc_nvram_register(struct rtc_device *rtc, { int err; - rtc->nvram = kzalloc(sizeof(struct bin_attribute), GFP_KERNEL); + rtc->nvram = kzalloc(sizeof(*rtc->nvram), GFP_KERNEL); if (!rtc->nvram) return -ENOMEM; diff --git a/drivers/rtc/proc.c b/drivers/rtc/proc.c index 4d74e4f4ff30..73344598fc1b 100644 --- a/drivers/rtc/proc.c +++ b/drivers/rtc/proc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, proc interface * @@ -5,11 +6,7 @@ * Author: Alessandro Zummo <a.zummo@towertech.it> * * based on arch/arm/common/rtctime.c - * - * 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. -*/ + */ #include <linux/module.h> #include <linux/rtc.h> @@ -60,17 +57,17 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) seq_printf(seq, "alrm_time\t: %ptRt\n", &alrm.time); seq_printf(seq, "alrm_date\t: %ptRd\n", &alrm.time); seq_printf(seq, "alarm_IRQ\t: %s\n", - alrm.enabled ? "yes" : "no"); + alrm.enabled ? "yes" : "no"); seq_printf(seq, "alrm_pending\t: %s\n", - alrm.pending ? "yes" : "no"); + alrm.pending ? "yes" : "no"); seq_printf(seq, "update IRQ enabled\t: %s\n", - (rtc->uie_rtctimer.enabled) ? "yes" : "no"); + (rtc->uie_rtctimer.enabled) ? "yes" : "no"); seq_printf(seq, "periodic IRQ enabled\t: %s\n", - (rtc->pie_enabled) ? "yes" : "no"); + (rtc->pie_enabled) ? "yes" : "no"); seq_printf(seq, "periodic IRQ frequency\t: %d\n", - rtc->irq_freq); + rtc->irq_freq); seq_printf(seq, "max user IRQ frequency\t: %d\n", - rtc->max_user_freq); + rtc->max_user_freq); } seq_printf(seq, "24hr\t\t: yes\n"); @@ -85,7 +82,7 @@ void rtc_proc_add_device(struct rtc_device *rtc) { if (is_rtc_hctosys(rtc)) proc_create_single_data("driver/rtc", 0, NULL, rtc_proc_show, - rtc); + rtc); } void rtc_proc_del_device(struct rtc_device *rtc) diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index 1fc48ebd3cd0..e4d5a19fd1c9 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -1,22 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Real Time Clock driver for Marvell 88PM80x PMIC * * Copyright (c) 2012 Marvell International Ltd. * Wenzeng Chen<wzch@marvell.com> * Qiao Zhou <zhouqiao@marvell.com> - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of this - * archive for more details. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/kernel.h> diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index d25282b4a7dd..73697e4b18a9 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -421,7 +421,7 @@ static int pm860x_rtc_remove(struct platform_device *pdev) struct pm860x_rtc_info *info = platform_get_drvdata(pdev); #ifdef VRTC_CALIBRATION - flush_scheduled_work(); + cancel_delayed_work_sync(&info->calib_work); /* disable measurement */ pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0); #endif /* VRTC_CALIBRATION */ diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index 2233601761ac..cdad6f00debf 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * rtc-ab-b5ze-s3 - Driver for Abracon AB-RTCMC-32.768Khz-B5ZE-S3 * I2C RTC / Alarm chip @@ -10,19 +11,9 @@ * * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c). * - * 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. */ #include <linux/module.h> -#include <linux/mutex.h> #include <linux/rtc.h> #include <linux/i2c.h> #include <linux/bcd.h> @@ -128,7 +119,6 @@ struct abb5zes3_rtc_data { struct rtc_device *rtc; struct regmap *regmap; - struct mutex lock; int irq; @@ -138,8 +128,7 @@ struct abb5zes3_rtc_data { /* * Try and match register bits w/ fixed null values to see whether we - * are dealing with an ABB5ZES3. Note: this function is called early - * during init and hence does need mutex protection. + * are dealing with an ABB5ZES3. */ static int abb5zes3_i2c_validate_chip(struct regmap *regmap) { @@ -230,14 +219,12 @@ static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm) if (ret) { dev_err(dev, "%s: reading RTC time failed (%d)\n", __func__, ret); - goto err; + return ret; } /* If clock integrity is not guaranteed, do not return a time value */ - if (regs[ABB5ZES3_REG_RTC_SC] & ABB5ZES3_REG_RTC_SC_OSC) { - ret = -ENODATA; - goto err; - } + if (regs[ABB5ZES3_REG_RTC_SC] & ABB5ZES3_REG_RTC_SC_OSC) + return -ENODATA; tm->tm_sec = bcd2bin(regs[ABB5ZES3_REG_RTC_SC] & 0x7F); tm->tm_min = bcd2bin(regs[ABB5ZES3_REG_RTC_MN]); @@ -255,7 +242,6 @@ static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mon = bcd2bin(regs[ABB5ZES3_REG_RTC_MO]) - 1; /* starts at 1 */ tm->tm_year = bcd2bin(regs[ABB5ZES3_REG_RTC_YR]) + 100; -err: return ret; } @@ -273,12 +259,9 @@ static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm) regs[ABB5ZES3_REG_RTC_MO] = bin2bcd(tm->tm_mon + 1); regs[ABB5ZES3_REG_RTC_YR] = bin2bcd(tm->tm_year - 100); - mutex_lock(&data->lock); ret = regmap_bulk_write(data->regmap, ABB5ZES3_REG_RTC_SC, regs + ABB5ZES3_REG_RTC_SC, ABB5ZES3_RTC_SEC_LEN); - mutex_unlock(&data->lock); - return ret; } @@ -332,38 +315,35 @@ static int _abb5zes3_rtc_read_timer(struct device *dev, if (ret) { dev_err(dev, "%s: reading Timer A section failed (%d)\n", __func__, ret); - goto err; + return ret; } /* get current time ... */ ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); if (ret) - goto err; + return ret; /* ... convert to seconds ... */ - ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (ret) - goto err; + rtc_secs = rtc_tm_to_time64(&rtc_tm); /* ... add remaining timer A time ... */ ret = sec_from_timer_a(&timer_secs, regs[1], regs[2]); if (ret) - goto err; + return ret; /* ... and convert back. */ - rtc_time_to_tm(rtc_secs + timer_secs, alarm_tm); + rtc_time64_to_tm(rtc_secs + timer_secs, alarm_tm); ret = regmap_read(data->regmap, ABB5ZES3_REG_CTRL2, ®); if (ret) { dev_err(dev, "%s: reading ctrl reg failed (%d)\n", __func__, ret); - goto err; + return ret; } alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL2_WTAIE); -err: - return ret; + return 0; } /* Read alarm currently configured via a RTC alarm registers. */ @@ -382,7 +362,7 @@ static int _abb5zes3_rtc_read_alarm(struct device *dev, if (ret) { dev_err(dev, "%s: reading alarm section failed (%d)\n", __func__, ret); - goto err; + return ret; } alarm_tm->tm_sec = 0; @@ -398,18 +378,13 @@ static int _abb5zes3_rtc_read_alarm(struct device *dev, */ ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); if (ret) - goto err; + return ret; alarm_tm->tm_year = rtc_tm.tm_year; alarm_tm->tm_mon = rtc_tm.tm_mon; - ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (ret) - goto err; - - ret = rtc_tm_to_time(alarm_tm, &alarm_secs); - if (ret) - goto err; + rtc_secs = rtc_tm_to_time64(&rtc_tm); + alarm_secs = rtc_tm_to_time64(alarm_tm); if (alarm_secs < rtc_secs) { if (alarm_tm->tm_mon == 11) { @@ -424,13 +399,12 @@ static int _abb5zes3_rtc_read_alarm(struct device *dev, if (ret) { dev_err(dev, "%s: reading ctrl reg failed (%d)\n", __func__, ret); - goto err; + return ret; } alarm->enabled = !!(reg & ABB5ZES3_REG_CTRL1_AIE); -err: - return ret; + return 0; } /* @@ -447,12 +421,10 @@ static int abb5zes3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); int ret; - mutex_lock(&data->lock); if (data->timer_alarm) ret = _abb5zes3_rtc_read_timer(dev, alarm); else ret = _abb5zes3_rtc_read_alarm(dev, alarm); - mutex_unlock(&data->lock); return ret; } @@ -466,33 +438,25 @@ static int _abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); struct rtc_time *alarm_tm = &alarm->time; - unsigned long rtc_secs, alarm_secs; u8 regs[ABB5ZES3_ALRM_SEC_LEN]; struct rtc_time rtc_tm; int ret, enable = 1; - ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); - if (ret) - goto err; - - ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (ret) - goto err; - - ret = rtc_tm_to_time(alarm_tm, &alarm_secs); - if (ret) - goto err; - - /* If alarm time is before current time, disable the alarm */ - if (!alarm->enabled || alarm_secs <= rtc_secs) { + if (!alarm->enabled) { enable = 0; } else { + unsigned long rtc_secs, alarm_secs; + /* * Chip only support alarms up to one month in the future. Let's * return an error if we get something after that limit. * Comparison is done by incrementing rtc_tm month field by one * and checking alarm value is still below. */ + ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); + if (ret) + return ret; + if (rtc_tm.tm_mon == 11) { /* handle year wrapping */ rtc_tm.tm_mon = 0; rtc_tm.tm_year += 1; @@ -500,15 +464,13 @@ static int _abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_tm.tm_mon += 1; } - ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (ret) - goto err; + rtc_secs = rtc_tm_to_time64(&rtc_tm); + alarm_secs = rtc_tm_to_time64(alarm_tm); if (alarm_secs > rtc_secs) { - dev_err(dev, "%s: alarm maximum is one month in the " - "future (%d)\n", __func__, ret); - ret = -EINVAL; - goto err; + dev_err(dev, "%s: alarm maximum is one month in the future (%d)\n", + __func__, ret); + return -EINVAL; } } @@ -526,17 +488,14 @@ static int _abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (ret < 0) { dev_err(dev, "%s: writing ALARM section failed (%d)\n", __func__, ret); - goto err; + return ret; } /* Record currently configured alarm is not a timer */ data->timer_alarm = 0; /* Enable or disable alarm interrupt generation */ - ret = _abb5zes3_rtc_update_alarm(dev, enable); - -err: - return ret; + return _abb5zes3_rtc_update_alarm(dev, enable); } /* @@ -557,7 +516,7 @@ static int _abb5zes3_rtc_set_timer(struct device *dev, struct rtc_wkalrm *alarm, ABB5ZES3_TIMA_SEC_LEN); if (ret < 0) { dev_err(dev, "%s: writing timer section failed\n", __func__); - goto err; + return ret; } /* Configure Timer A as a watchdog timer */ @@ -570,10 +529,7 @@ static int _abb5zes3_rtc_set_timer(struct device *dev, struct rtc_wkalrm *alarm, data->timer_alarm = 1; /* Enable or disable timer interrupt generation */ - ret = _abb5zes3_rtc_update_timer(dev, alarm->enabled); - -err: - return ret; + return _abb5zes3_rtc_update_timer(dev, alarm->enabled); } /* @@ -590,31 +546,25 @@ static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct rtc_time rtc_tm; int ret; - mutex_lock(&data->lock); ret = _abb5zes3_rtc_read_time(dev, &rtc_tm); if (ret) - goto err; + return ret; - ret = rtc_tm_to_time(&rtc_tm, &rtc_secs); - if (ret) - goto err; - - ret = rtc_tm_to_time(alarm_tm, &alarm_secs); - if (ret) - goto err; + rtc_secs = rtc_tm_to_time64(&rtc_tm); + alarm_secs = rtc_tm_to_time64(alarm_tm); /* Let's first disable both the alarm and the timer interrupts */ ret = _abb5zes3_rtc_update_alarm(dev, false); if (ret < 0) { dev_err(dev, "%s: unable to disable alarm (%d)\n", __func__, ret); - goto err; + return ret; } ret = _abb5zes3_rtc_update_timer(dev, false); if (ret < 0) { dev_err(dev, "%s: unable to disable timer (%d)\n", __func__, ret); - goto err; + return ret; } data->timer_alarm = 0; @@ -629,9 +579,6 @@ static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) else ret = _abb5zes3_rtc_set_alarm(dev, alarm); - err: - mutex_unlock(&data->lock); - if (ret) dev_err(dev, "%s: unable to configure alarm (%d)\n", __func__, ret); @@ -650,8 +597,7 @@ static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap, /* * Check current RTC status and enable/disable what needs to be. Return 0 if - * everything went ok and a negative value upon error. Note: this function - * is called early during init and hence does need mutex protection. + * everything went ok and a negative value upon error. */ static int abb5zes3_rtc_check_setup(struct device *dev) { @@ -675,8 +621,9 @@ static int abb5zes3_rtc_check_setup(struct device *dev) ABB5ZES3_REG_TIM_CLK_COF1 | ABB5ZES3_REG_TIM_CLK_COF2 | ABB5ZES3_REG_TIM_CLK_TBM | ABB5ZES3_REG_TIM_CLK_TAM); ret = regmap_update_bits(regmap, ABB5ZES3_REG_TIM_CLK, mask, - ABB5ZES3_REG_TIM_CLK_COF0 | ABB5ZES3_REG_TIM_CLK_COF1 | - ABB5ZES3_REG_TIM_CLK_COF2); + ABB5ZES3_REG_TIM_CLK_COF0 | + ABB5ZES3_REG_TIM_CLK_COF1 | + ABB5ZES3_REG_TIM_CLK_COF2); if (ret < 0) { dev_err(dev, "%s: unable to initialize clkout register (%d)\n", __func__, ret); @@ -729,9 +676,9 @@ static int abb5zes3_rtc_check_setup(struct device *dev) * switchover flag but not battery low flag. The latter is checked * later below. */ - mask = (ABB5ZES3_REG_CTRL3_PM0 | ABB5ZES3_REG_CTRL3_PM1 | - ABB5ZES3_REG_CTRL3_PM2 | ABB5ZES3_REG_CTRL3_BLIE | - ABB5ZES3_REG_CTRL3_BSIE| ABB5ZES3_REG_CTRL3_BSF); + mask = (ABB5ZES3_REG_CTRL3_PM0 | ABB5ZES3_REG_CTRL3_PM1 | + ABB5ZES3_REG_CTRL3_PM2 | ABB5ZES3_REG_CTRL3_BLIE | + ABB5ZES3_REG_CTRL3_BSIE | ABB5ZES3_REG_CTRL3_BSF); ret = regmap_update_bits(regmap, ABB5ZES3_REG_CTRL3, mask, 0); if (ret < 0) { dev_err(dev, "%s: unable to initialize CTRL3 register (%d)\n", @@ -748,10 +695,8 @@ static int abb5zes3_rtc_check_setup(struct device *dev) } if (reg & ABB5ZES3_REG_RTC_SC_OSC) { - dev_err(dev, "clock integrity not guaranteed. Osc. has stopped " - "or has been interrupted.\n"); - dev_err(dev, "change battery (if not already done) and " - "then set time to reset osc. failure flag.\n"); + dev_err(dev, "clock integrity not guaranteed. Osc. has stopped or has been interrupted.\n"); + dev_err(dev, "change battery (if not already done) and then set time to reset osc. failure flag.\n"); } /* @@ -769,13 +714,12 @@ static int abb5zes3_rtc_check_setup(struct device *dev) data->battery_low = reg & ABB5ZES3_REG_CTRL3_BLF; if (data->battery_low) { - dev_err(dev, "RTC battery is low; please, consider " - "changing it!\n"); + dev_err(dev, "RTC battery is low; please, consider changing it!\n"); ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, false); if (ret) - dev_err(dev, "%s: disabling battery low interrupt " - "generation failed (%d)\n", __func__, ret); + dev_err(dev, "%s: disabling battery low interrupt generation failed (%d)\n", + __func__, ret); } return ret; @@ -788,12 +732,10 @@ static int abb5zes3_rtc_alarm_irq_enable(struct device *dev, int ret = 0; if (rtc_data->irq) { - mutex_lock(&rtc_data->lock); if (rtc_data->timer_alarm) ret = _abb5zes3_rtc_update_timer(dev, enable); else ret = _abb5zes3_rtc_update_alarm(dev, enable); - mutex_unlock(&rtc_data->lock); } return ret; @@ -885,49 +827,44 @@ static int abb5zes3_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_I2C_BLOCK)) { - ret = -ENODEV; - goto err; - } + I2C_FUNC_SMBUS_I2C_BLOCK)) + return -ENODEV; regmap = devm_regmap_init_i2c(client, &abb5zes3_rtc_regmap_config); if (IS_ERR(regmap)) { ret = PTR_ERR(regmap); dev_err(dev, "%s: regmap allocation failed: %d\n", __func__, ret); - goto err; + return ret; } ret = abb5zes3_i2c_validate_chip(regmap); if (ret) - goto err; + return ret; data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) { - ret = -ENOMEM; - goto err; - } + if (!data) + return -ENOMEM; - mutex_init(&data->lock); data->regmap = regmap; dev_set_drvdata(dev, data); ret = abb5zes3_rtc_check_setup(dev); if (ret) - goto err; + return ret; data->rtc = devm_rtc_allocate_device(dev); ret = PTR_ERR_OR_ZERO(data->rtc); if (ret) { dev_err(dev, "%s: unable to allocate RTC device (%d)\n", __func__, ret); - goto err; + return ret; } if (client->irq > 0) { ret = devm_request_threaded_irq(dev, client->irq, NULL, _abb5zes3_rtc_interrupt, - IRQF_SHARED|IRQF_ONESHOT, + IRQF_SHARED | IRQF_ONESHOT, DRV_NAME, client); if (!ret) { device_init_wakeup(dev, true); @@ -949,8 +886,8 @@ static int abb5zes3_probe(struct i2c_client *client, if (!data->battery_low && data->irq) { ret = _abb5zes3_rtc_battery_low_irq_enable(regmap, true); if (ret) { - dev_err(dev, "%s: enabling battery low interrupt " - "generation failed (%d)\n", __func__, ret); + dev_err(dev, "%s: enabling battery low interrupt generation failed (%d)\n", + __func__, ret); goto err; } } @@ -958,7 +895,7 @@ static int abb5zes3_probe(struct i2c_client *client, ret = rtc_register_device(data->rtc); err: - if (ret && data && data->irq) + if (ret && data->irq) device_init_wakeup(dev, false); return ret; } diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index 821ff52a2222..2ed6def90975 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 * RTC clock driver for the AB3100 Analog Baseband Chip * Author: Linus Walleij <linus.walleij@stericsson.com> */ @@ -43,12 +43,12 @@ /* * RTC clock functions and device struct declaration */ -static int ab3100_rtc_set_mmss(struct device *dev, time64_t secs) +static int ab3100_rtc_set_time(struct device *dev, struct rtc_time *tm) { u8 regs[] = {AB3100_TI0, AB3100_TI1, AB3100_TI2, AB3100_TI3, AB3100_TI4, AB3100_TI5}; unsigned char buf[6]; - u64 hw_counter = secs * AB3100_RTC_CLOCK_RATE * 2; + u64 hw_counter = rtc_tm_to_time64(tm) * AB3100_RTC_CLOCK_RATE * 2; int err = 0; int i; @@ -192,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_mmss64 = ab3100_rtc_set_mmss, + .set_time = ab3100_rtc_set_time, .read_alarm = ab3100_rtc_read_alarm, .set_alarm = ab3100_rtc_set_alarm, .alarm_irq_enable = ab3100_rtc_irq_enable, @@ -228,15 +228,17 @@ static int __init ab3100_rtc_probe(struct platform_device *pdev) /* Ignore any error on this write */ } - rtc = devm_rtc_device_register(&pdev->dev, "ab3100-rtc", - &ab3100_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - return err; - } + rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + rtc->ops = &ab3100_rtc_ops; + /* 48bit counter at (AB3100_RTC_CLOCK_RATE * 2) */ + rtc->range_max = U32_MAX; + platform_set_drvdata(pdev, rtc); - return 0; + return rtc_register_device(rtc); } static struct platform_driver ab3100_rtc_driver = { diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index 6ddcad642d1e..73830670a41f 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * A driver for the I2C members of the Abracon AB x8xx RTC family, * and compatible: AB 1805 and AB 0805 @@ -7,10 +8,6 @@ * Author: Philippe De Muyter <phdm@macqel.be> * Author: Alexandre Belloni <alexandre.belloni@bootlin.com> * - * 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. - * */ #include <linux/bcd.h> @@ -404,7 +401,7 @@ static ssize_t autocalibration_store(struct device *dev, return -EINVAL; } - retval = abx80x_rtc_set_autocalibration(dev, autocalibration); + retval = abx80x_rtc_set_autocalibration(dev->parent, autocalibration); return retval ? retval : count; } @@ -414,7 +411,7 @@ static ssize_t autocalibration_show(struct device *dev, { int autocalibration = 0; - autocalibration = abx80x_rtc_get_autocalibration(dev); + autocalibration = abx80x_rtc_get_autocalibration(dev->parent); if (autocalibration < 0) { dev_err(dev, "Failed to read RTC autocalibration\n"); sprintf(buf, "0\n"); @@ -430,7 +427,7 @@ static ssize_t oscillator_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); int retval, flags, rc_mode = 0; if (strncmp(buf, "rc", 2) == 0) { @@ -472,7 +469,7 @@ static ssize_t oscillator_show(struct device *dev, struct device_attribute *attr, char *buf) { int rc_mode = 0; - struct i2c_client *client = to_i2c_client(dev); + struct i2c_client *client = to_i2c_client(dev->parent); rc_mode = abx80x_is_rc_mode(client); @@ -592,13 +589,6 @@ static int abx80x_dt_trickle_cfg(struct device_node *np) return (trickle_cfg | i); } -static void rtc_calib_remove_sysfs_group(void *_dev) -{ - struct device *dev = _dev; - - sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group); -} - #ifdef CONFIG_WATCHDOG static inline u8 timeout_bits(unsigned int timeout) @@ -851,32 +841,14 @@ static int abx80x_probe(struct i2c_client *client, } } - /* Export sysfs entries */ - err = sysfs_create_group(&(&client->dev)->kobj, &rtc_calib_attr_group); + err = rtc_add_group(priv->rtc, &rtc_calib_attr_group); if (err) { dev_err(&client->dev, "Failed to create sysfs group: %d\n", err); return err; } - err = devm_add_action_or_reset(&client->dev, - rtc_calib_remove_sysfs_group, - &client->dev); - if (err) { - dev_err(&client->dev, - "Failed to add sysfs cleanup action: %d\n", - err); - return err; - } - - err = rtc_register_device(priv->rtc); - - return err; -} - -static int abx80x_remove(struct i2c_client *client) -{ - return 0; + return rtc_register_device(priv->rtc); } static const struct i2c_device_id abx80x_id[] = { @@ -899,7 +871,6 @@ static struct i2c_driver abx80x_driver = { .name = "rtc-abx80x", }, .probe = abx80x_probe, - .remove = abx80x_remove, .id_table = abx80x_id, }; diff --git a/drivers/rtc/rtc-aspeed.c b/drivers/rtc/rtc-aspeed.c new file mode 100644 index 000000000000..af3eb676d7c3 --- /dev/null +++ b/drivers/rtc/rtc-aspeed.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright 2015 IBM Corp. + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> +#include <linux/io.h> + +struct aspeed_rtc { + struct rtc_device *rtc_dev; + void __iomem *base; +}; + +#define RTC_TIME 0x00 +#define RTC_YEAR 0x04 +#define RTC_CTRL 0x10 + +#define RTC_UNLOCK BIT(1) +#define RTC_ENABLE BIT(0) + +static int aspeed_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct aspeed_rtc *rtc = dev_get_drvdata(dev); + unsigned int cent, year; + u32 reg1, reg2; + + if (!(readl(rtc->base + RTC_CTRL) & RTC_ENABLE)) { + dev_dbg(dev, "%s failing as rtc disabled\n", __func__); + return -EINVAL; + } + + do { + reg2 = readl(rtc->base + RTC_YEAR); + reg1 = readl(rtc->base + RTC_TIME); + } while (reg2 != readl(rtc->base + RTC_YEAR)); + + tm->tm_mday = (reg1 >> 24) & 0x1f; + tm->tm_hour = (reg1 >> 16) & 0x1f; + tm->tm_min = (reg1 >> 8) & 0x3f; + tm->tm_sec = (reg1 >> 0) & 0x3f; + + cent = (reg2 >> 16) & 0x1f; + year = (reg2 >> 8) & 0x7f; + tm->tm_mon = ((reg2 >> 0) & 0x0f) - 1; + tm->tm_year = year + (cent * 100) - 1900; + + dev_dbg(dev, "%s %ptR", __func__, tm); + + return 0; +} + +static int aspeed_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct aspeed_rtc *rtc = dev_get_drvdata(dev); + u32 reg1, reg2, ctrl; + int year, cent; + + cent = (tm->tm_year + 1900) / 100; + year = tm->tm_year % 100; + + reg1 = (tm->tm_mday << 24) | (tm->tm_hour << 16) | (tm->tm_min << 8) | + tm->tm_sec; + + reg2 = ((cent & 0x1f) << 16) | ((year & 0x7f) << 8) | + ((tm->tm_mon + 1) & 0xf); + + ctrl = readl(rtc->base + RTC_CTRL); + writel(ctrl | RTC_UNLOCK, rtc->base + RTC_CTRL); + + writel(reg1, rtc->base + RTC_TIME); + writel(reg2, rtc->base + RTC_YEAR); + + /* Re-lock and ensure enable is set now that a time is programmed */ + writel(ctrl | RTC_ENABLE, rtc->base + RTC_CTRL); + + return 0; +} + +static const struct rtc_class_ops aspeed_rtc_ops = { + .read_time = aspeed_rtc_read_time, + .set_time = aspeed_rtc_set_time, +}; + +static int aspeed_rtc_probe(struct platform_device *pdev) +{ + struct aspeed_rtc *rtc; + struct resource *res; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rtc->base)) + return PTR_ERR(rtc->base); + + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + + platform_set_drvdata(pdev, rtc); + + rtc->rtc_dev->ops = &aspeed_rtc_ops; + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; + rtc->rtc_dev->range_max = 38814989399LL; /* 3199-12-31 23:59:59 */ + + ret = rtc_register_device(rtc->rtc_dev); + if (ret) + return ret; + + return 0; +} + +static const struct of_device_id aspeed_rtc_match[] = { + { .compatible = "aspeed,ast2400-rtc", }, + { .compatible = "aspeed,ast2500-rtc", }, + { .compatible = "aspeed,ast2600-rtc", }, + {} +}; +MODULE_DEVICE_TABLE(of, aspeed_rtc_match); + +static struct platform_driver aspeed_rtc_driver = { + .driver = { + .name = "aspeed-rtc", + .of_match_table = of_match_ptr(aspeed_rtc_match), + }, +}; + +module_platform_driver_probe(aspeed_rtc_driver, aspeed_rtc_probe); + +MODULE_DESCRIPTION("ASPEED RTC driver"); +MODULE_AUTHOR("Joel Stanley <joel@jms.id.au>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 1d31c0ae6334..4daf3789b978 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * "RTT as Real Time Clock" driver for AT91SAM9 SoC family * * (C) 2007 Michel Benoit * * Based on rtc-at91rm9200.c by Rick Bronson - * - * 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/clk.h> @@ -47,21 +43,21 @@ * registers available, likewise usable for more than "RTC" support. */ -#define AT91_RTT_MR 0x00 /* Real-time Mode Register */ -#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */ -#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */ -#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */ -#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */ +#define AT91_RTT_MR 0x00 /* Real-time Mode Register */ +#define AT91_RTT_RTPRES (0xffff << 0) /* Timer Prescaler Value */ +#define AT91_RTT_ALMIEN BIT(16) /* Alarm Interrupt Enable */ +#define AT91_RTT_RTTINCIEN BIT(17) /* Increment Interrupt Enable */ +#define AT91_RTT_RTTRST BIT(18) /* Timer Restart */ -#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */ -#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ +#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */ +#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */ -#define AT91_RTT_VR 0x08 /* Real-time Value Register */ -#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ +#define AT91_RTT_VR 0x08 /* Real-time Value Register */ +#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */ -#define AT91_RTT_SR 0x0c /* Real-time Status Register */ -#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */ -#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */ +#define AT91_RTT_SR 0x0c /* Real-time Status Register */ +#define AT91_RTT_ALMS BIT(0) /* Alarm Status */ +#define AT91_RTT_RTTINC BIT(1) /* Timer Increment */ /* * We store ALARM_DISABLED in ALMV to record that no alarm is set. @@ -69,14 +65,13 @@ */ #define ALARM_DISABLED ((u32)~0) - struct sam9_rtc { void __iomem *rtt; struct rtc_device *rtcdev; u32 imr; struct regmap *gpbr; unsigned int gpbr_offset; - int irq; + int irq; struct clk *sclk; bool suspended; unsigned long events; @@ -122,7 +117,7 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) if (secs != secs2) secs = rtt_readl(rtc, VR); - rtc_time_to_tm(offset + secs, tm); + rtc_time64_to_tm(offset + secs, tm); dev_dbg(dev, "%s: %ptR\n", __func__, tm); @@ -135,15 +130,12 @@ static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) { struct sam9_rtc *rtc = dev_get_drvdata(dev); - int err; u32 offset, alarm, mr; unsigned long secs; dev_dbg(dev, "%s: %ptR\n", __func__, tm); - err = rtc_tm_to_time(tm, &secs); - if (err != 0) - return err; + secs = rtc_tm_to_time64(tm); mr = rtt_readl(rtc, MR); @@ -193,7 +185,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) memset(alrm, 0, sizeof(*alrm)); if (alarm != ALARM_DISABLED && offset != 0) { - rtc_time_to_tm(offset + alarm, tm); + rtc_time64_to_tm(offset + alarm, tm); dev_dbg(dev, "%s: %ptR\n", __func__, tm); @@ -211,11 +203,8 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) unsigned long secs; u32 offset; u32 mr; - int err; - err = rtc_tm_to_time(tm, &secs); - if (err != 0) - return err; + secs = rtc_tm_to_time64(tm); offset = gpbr_readl(rtc); if (offset == 0) { @@ -263,7 +252,7 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) u32 mr = rtt_readl(rtc, MR); seq_printf(seq, "update_IRQ\t: %s\n", - (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); + (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); return 0; } @@ -299,7 +288,7 @@ static void at91_rtc_flush_events(struct sam9_rtc *rtc) rtc->events = 0; pr_debug("%s: num=%ld, events=0x%02lx\n", __func__, - rtc->events >> 8, rtc->events & 0x000000FF); + rtc->events >> 8, rtc->events & 0x000000FF); } /* @@ -340,13 +329,6 @@ static const struct rtc_class_ops at91_rtc_ops = { .alarm_irq_enable = at91_rtc_alarm_irq_enable, }; -static const struct regmap_config gpbr_regmap_config = { - .name = "gpbr", - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, -}; - /* * Initialize and install RTC driver */ @@ -357,6 +339,7 @@ static int at91_rtc_probe(struct platform_device *pdev) int ret, irq; u32 mr; unsigned int sclk_rate; + struct of_phandle_args args; irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -382,34 +365,14 @@ static int at91_rtc_probe(struct platform_device *pdev) if (IS_ERR(rtc->rtt)) return PTR_ERR(rtc->rtt); - if (!pdev->dev.of_node) { - /* - * TODO: Remove this code chunk when removing non DT board - * support. Remember to remove the gpbr_regmap_config - * variable too. - */ - void __iomem *gpbr; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 1); - gpbr = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(gpbr)) - return PTR_ERR(gpbr); - - rtc->gpbr = regmap_init_mmio(NULL, gpbr, - &gpbr_regmap_config); - } else { - struct of_phandle_args args; - - ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, - "atmel,rtt-rtc-time-reg", 1, 0, - &args); - if (ret) - return ret; - - rtc->gpbr = syscon_node_to_regmap(args.np); - rtc->gpbr_offset = args.args[0]; - } + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, + "atmel,rtt-rtc-time-reg", 1, 0, + &args); + if (ret) + return ret; + rtc->gpbr = syscon_node_to_regmap(args.np); + rtc->gpbr_offset = args.args[0]; if (IS_ERR(rtc->gpbr)) { dev_err(&pdev->dev, "failed to retrieve gpbr regmap, aborting.\n"); return -ENOMEM; @@ -444,13 +407,15 @@ static int at91_rtc_probe(struct platform_device *pdev) mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); rtt_writel(rtc, MR, mr); - rtc->rtcdev = devm_rtc_device_register(&pdev->dev, pdev->name, - &at91_rtc_ops, THIS_MODULE); + rtc->rtcdev = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtcdev)) { ret = PTR_ERR(rtc->rtcdev); goto err_clk; } + rtc->rtcdev->ops = &at91_rtc_ops; + rtc->rtcdev->range_max = U32_MAX; + /* register irq handler after we know what name we'll use */ ret = devm_request_irq(&pdev->dev, rtc->irq, at91_rtc_interrupt, IRQF_SHARED | IRQF_COND_SUSPEND, @@ -468,9 +433,9 @@ static int at91_rtc_probe(struct platform_device *pdev) if (gpbr_readl(rtc) == 0) dev_warn(&pdev->dev, "%s: SET TIME!\n", - dev_name(&rtc->rtcdev->dev)); + dev_name(&rtc->rtcdev->dev)); - return 0; + return rtc_register_device(rtc->rtcdev); err_clk: clk_disable_unprepare(rtc->sclk); @@ -528,8 +493,9 @@ static int at91_rtc_suspend(struct device *dev) /* don't let RTTINC cause wakeups */ if (mr & AT91_RTT_RTTINCIEN) rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); - } else + } else { rtt_writel(rtc, MR, mr & ~rtc->imr); + } } return 0; @@ -561,13 +527,11 @@ static int at91_rtc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(at91_rtc_pm_ops, at91_rtc_suspend, at91_rtc_resume); -#ifdef CONFIG_OF static const struct of_device_id at91_rtc_dt_ids[] = { { .compatible = "atmel,at91sam9260-rtt" }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, at91_rtc_dt_ids); -#endif static struct platform_driver at91_rtc_driver = { .probe = at91_rtc_probe, diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c index f4010a75f2be..a193396a8140 100644 --- a/drivers/rtc/rtc-brcmstb-waketimer.c +++ b/drivers/rtc/rtc-brcmstb-waketimer.c @@ -132,7 +132,7 @@ static int brcmstb_waketmr_gettime(struct device *dev, wktmr_read(timer, &now); - rtc_time_to_tm(now.sec, tm); + rtc_time64_to_tm(now.sec, tm); return 0; } diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 0b232c84f674..4ac850837153 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -1,6 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 * Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC. * Author: Linus Walleij <linus.walleij@stericsson.com> * Based on rtc-pl031.c by Deepak Saxena <dsaxena@plexity.net> @@ -80,21 +80,22 @@ static int coh901331_read_time(struct device *dev, struct rtc_time *tm) clk_enable(rtap->clk); /* Check if the time is valid */ - if (readl(rtap->virtbase + COH901331_VALID)) { - rtc_time_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); + if (!readl(rtap->virtbase + COH901331_VALID)) { clk_disable(rtap->clk); - return 0; + return -EINVAL; } + + rtc_time64_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); clk_disable(rtap->clk); - return -EINVAL; + return 0; } -static int coh901331_set_mmss(struct device *dev, unsigned long secs) +static int coh901331_set_time(struct device *dev, struct rtc_time *tm) { struct coh901331_port *rtap = dev_get_drvdata(dev); clk_enable(rtap->clk); - writel(secs, rtap->virtbase + COH901331_SET_TIME); + writel(rtc_tm_to_time64(tm), rtap->virtbase + COH901331_SET_TIME); clk_disable(rtap->clk); return 0; @@ -105,7 +106,7 @@ static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct coh901331_port *rtap = dev_get_drvdata(dev); clk_enable(rtap->clk); - rtc_time_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); + rtc_time64_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U; alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U; clk_disable(rtap->clk); @@ -116,9 +117,8 @@ static int coh901331_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct coh901331_port *rtap = dev_get_drvdata(dev); - unsigned long time; + unsigned long time = rtc_tm_to_time64(&alarm->time); - rtc_tm_to_time(&alarm->time, &time); clk_enable(rtap->clk); writel(time, rtap->virtbase + COH901331_ALARM); writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK); @@ -143,7 +143,7 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled) static const struct rtc_class_ops coh901331_ops = { .read_time = coh901331_read_time, - .set_mmss = coh901331_set_mmss, + .set_time = coh901331_set_time, .read_alarm = coh901331_read_alarm, .set_alarm = coh901331_set_alarm, .alarm_irq_enable = coh901331_alarm_irq_enable, @@ -188,6 +188,13 @@ static int __init coh901331_probe(struct platform_device *pdev) return ret; } + rtap->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtap->rtc)) + return PTR_ERR(rtap->rtc); + + rtap->rtc->ops = &coh901331_ops; + rtap->rtc->range_max = U32_MAX; + /* We enable/disable the clock only to assure it works */ ret = clk_prepare_enable(rtap->clk); if (ret) { @@ -197,12 +204,10 @@ static int __init coh901331_probe(struct platform_device *pdev) clk_disable(rtap->clk); platform_set_drvdata(pdev, rtap); - rtap->rtc = devm_rtc_device_register(&pdev->dev, "coh901331", - &coh901331_ops, THIS_MODULE); - if (IS_ERR(rtap->rtc)) { - ret = PTR_ERR(rtap->rtc); + + ret = rtc_register_device(rtap->rtc); + if (ret) goto out_no_rtc; - } return 0; diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 69b54e5556c0..15908d51b1cb 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -1,15 +1,7 @@ -/* rtc-da9063.c - Real time clock device driver for DA9063 +// SPDX-License-Identifier: GPL-2.0+ +/* + * Real time clock device driver for DA9063 * Copyright (C) 2013-2015 Dialog Semiconductor Ltd. - * - * 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. */ #include <linux/delay.h> @@ -247,8 +239,8 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) da9063_data_to_tm(data, tm, rtc); - rtc_tm_to_time(tm, &tm_secs); - rtc_tm_to_time(&rtc->alarm_time, &al_secs); + tm_secs = rtc_tm_to_time64(tm); + al_secs = rtc_tm_to_time64(&rtc->alarm_time); /* handle the rtc synchronisation delay */ if (rtc->rtc_sync == true && al_secs - tm_secs == 1) @@ -472,11 +464,14 @@ static int da9063_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, DA9063_DRVNAME_RTC, - &da9063_rtc_ops, THIS_MODULE); + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtc_dev)) return PTR_ERR(rtc->rtc_dev); + rtc->rtc_dev->ops = &da9063_rtc_ops; + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_2063; + da9063_data_to_tm(data, &rtc->alarm_time, rtc); rtc->rtc_sync = false; @@ -496,7 +491,7 @@ static int da9063_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to request ALARM IRQ %d: %d\n", irq_alarm, ret); - return ret; + return rtc_register_device(rtc->rtc_dev); } static struct platform_driver da9063_rtc_driver = { diff --git a/drivers/rtc/rtc-digicolor.c b/drivers/rtc/rtc-digicolor.c index b253bf1b3531..0aecc3f8e721 100644 --- a/drivers/rtc/rtc-digicolor.c +++ b/drivers/rtc/rtc-digicolor.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * 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> @@ -106,11 +102,11 @@ static int dc_rtc_read_time(struct device *dev, struct rtc_time *tm) return 0; } -static int dc_rtc_set_mmss(struct device *dev, unsigned long secs) +static int dc_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct dc_rtc *rtc = dev_get_drvdata(dev); - return dc_rtc_write(rtc, secs); + return dc_rtc_write(rtc, rtc_tm_to_time64(tm)); } static int dc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) @@ -161,7 +157,7 @@ static int dc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static const struct rtc_class_ops dc_rtc_ops = { .read_time = dc_rtc_read_time, - .set_mmss = dc_rtc_set_mmss, + .set_time = dc_rtc_set_time, .read_alarm = dc_rtc_read_alarm, .set_alarm = dc_rtc_set_alarm, .alarm_irq_enable = dc_rtc_alarm_irq_enable, @@ -192,6 +188,10 @@ static int __init dc_rtc_probe(struct platform_device *pdev) if (IS_ERR(rtc->regs)) return PTR_ERR(rtc->regs); + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; @@ -200,12 +200,11 @@ static int __init dc_rtc_probe(struct platform_device *pdev) 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; + rtc->rtc_dev->ops = &dc_rtc_ops; + rtc->rtc_dev->range_max = U32_MAX; + + return rtc_register_device(rtc->rtc_dev); } static const struct of_device_id dc_dt_ids[] = { diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c index 97d8259b9494..cd947a20843b 100644 --- a/drivers/rtc/rtc-dm355evm.c +++ b/drivers/rtc/rtc-dm355evm.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * rtc-dm355evm.c - access battery-backed counter in MSP430 firmware * * Copyright (c) 2008 by David Brownell - * - * 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/kernel.h> #include <linux/init.h> @@ -78,7 +74,7 @@ static int dm355evm_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_dbg(dev, "read timestamp %08x\n", time.value); - rtc_time_to_tm(le32_to_cpu(time.value), tm); + rtc_time64_to_tm(le32_to_cpu(time.value), tm); return 0; } @@ -88,7 +84,7 @@ static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned long value; int status; - rtc_tm_to_time(tm, &value); + value = rtc_tm_to_time64(tm); time.value = cpu_to_le32(value); dev_dbg(dev, "write timestamp %08x\n", time.value); @@ -127,16 +123,16 @@ static int dm355evm_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &dm355evm_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - dev_err(&pdev->dev, "can't register RTC device, err %ld\n", - PTR_ERR(rtc)); + rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc)) return PTR_ERR(rtc); - } + platform_set_drvdata(pdev, rtc); - return 0; + rtc->ops = &dm355evm_rtc_ops; + rtc->range_max = U32_MAX; + + return rtc_register_device(rtc); } /* diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c index b1ebca099b0d..e9e8d02743ee 100644 --- a/drivers/rtc/rtc-ds1672.c +++ b/drivers/rtc/rtc-ds1672.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * An rtc/i2c driver for the Dallas DS1672 * Copyright 2005-06 Tower Technologies * * Author: Alessandro Zummo <a.zummo@towertech.it> - * - * 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. */ #include <linux/i2c.h> @@ -21,17 +18,16 @@ #define DS1672_REG_CONTROL_EOSC 0x80 -static struct i2c_driver ds1672_driver; - /* * In the routines that deal directly with the ds1672 hardware, we use * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch - * Epoch is initialized as 2000. Time is set to UTC. + * Time is set to UTC. */ -static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) +static int ds1672_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); unsigned long time; - unsigned char addr = DS1672_REG_CNT_BASE; + unsigned char addr = DS1672_REG_CONTROL; unsigned char buf[4]; struct i2c_msg msgs[] = { @@ -43,11 +39,25 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) {/* read date */ .addr = client->addr, .flags = I2C_M_RD, - .len = 4, + .len = 1, .buf = buf }, }; + /* read control register */ + if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { + dev_warn(&client->dev, "Unable to read the control register\n"); + return -EIO; + } + + if (buf[0] & DS1672_REG_CONTROL_EOSC) { + dev_warn(&client->dev, "Oscillator not enabled. Set time to enable.\n"); + return -EINVAL; + } + + addr = DS1672_REG_CNT_BASE; + msgs[1].len = 4; + /* read date registers */ if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { dev_err(&client->dev, "%s: read error\n", __func__); @@ -61,20 +71,19 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm) time = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; - rtc_time_to_tm(time, tm); + rtc_time64_to_tm(time, tm); - dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, " - "mday=%d, mon=%d, year=%d, wday=%d\n", - __func__, tm->tm_sec, tm->tm_min, tm->tm_hour, - tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); + dev_dbg(&client->dev, "%s: tm is %ptR\n", __func__, tm); return 0; } -static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) +static int ds1672_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); int xfer; unsigned char buf[6]; + unsigned long secs = rtc_tm_to_time64(tm); buf[0] = DS1672_REG_CNT_BASE; buf[1] = secs & 0x000000FF; @@ -92,71 +101,15 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs) return 0; } -static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return ds1672_get_datetime(to_i2c_client(dev), tm); -} - -static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs) -{ - return ds1672_set_mmss(to_i2c_client(dev), secs); -} - -static int ds1672_get_control(struct i2c_client *client, u8 *status) -{ - unsigned char addr = DS1672_REG_CONTROL; - - struct i2c_msg msgs[] = { - {/* setup read ptr */ - .addr = client->addr, - .len = 1, - .buf = &addr - }, - {/* read control */ - .addr = client->addr, - .flags = I2C_M_RD, - .len = 1, - .buf = status - }, - }; - - /* read control register */ - if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) { - dev_err(&client->dev, "%s: read error\n", __func__); - return -EIO; - } - - return 0; -} - -/* following are the sysfs callback functions */ -static ssize_t show_control(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - u8 control; - int err; - - err = ds1672_get_control(client, &control); - if (err) - return err; - - return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC) - ? "disabled" : "enabled"); -} - -static DEVICE_ATTR(control, S_IRUGO, show_control, NULL); - static const struct rtc_class_ops ds1672_rtc_ops = { - .read_time = ds1672_rtc_read_time, - .set_mmss = ds1672_rtc_set_mmss, + .read_time = ds1672_read_time, + .set_time = ds1672_set_time, }; static int ds1672_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; - u8 control; struct rtc_device *rtc; dev_dbg(&client->dev, "%s\n", __func__); @@ -164,29 +117,21 @@ static int ds1672_probe(struct i2c_client *client, if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; - rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name, - &ds1672_rtc_ops, THIS_MODULE); - + rtc = devm_rtc_allocate_device(&client->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); - i2c_set_clientdata(client, rtc); + rtc->ops = &ds1672_rtc_ops; + rtc->range_max = U32_MAX; - /* read control register */ - err = ds1672_get_control(client, &control); - if (err) { - dev_warn(&client->dev, "Unable to read the control register\n"); - } + err = rtc_register_device(rtc); + if (err) + return err; - if (control & DS1672_REG_CONTROL_EOSC) - dev_warn(&client->dev, "Oscillator not enabled. " - "Set time to enable.\n"); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); - /* Register sysfs hooks */ - err = device_create_file(&client->dev, &dev_attr_control); - if (err) - dev_err(&client->dev, "Unable to create sysfs entry: %s\n", - dev_attr_control.attr.name); + i2c_set_clientdata(client, rtc); return 0; } diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 2710f2594c42..5f4328524183 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -192,42 +192,6 @@ ds1685_rtc_end_data_access(struct ds1685_priv *rtc) } /** - * ds1685_rtc_begin_ctrl_access - prepare the rtc for ctrl access. - * @rtc: pointer to the ds1685 rtc structure. - * @flags: irq flags variable for spin_lock_irqsave. - * - * This takes several steps to prepare the rtc for access to read just the - * control registers: - * - Sets a spinlock on the rtc IRQ. - * - Switches the rtc to bank 1. This allows access to the two extended - * control registers. - * - * Only use this where you are certain another lock will not be held. - */ -static inline void -ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long *flags) -{ - spin_lock_irqsave(&rtc->lock, *flags); - ds1685_rtc_switch_to_bank1(rtc); -} - -/** - * ds1685_rtc_end_ctrl_access - end ctrl access on the rtc. - * @rtc: pointer to the ds1685 rtc structure. - * @flags: irq flags variable for spin_unlock_irqrestore. - * - * This ends what was started by ds1685_rtc_begin_ctrl_access: - * - Switches the rtc back to bank 0. - * - Unsets the spinlock on the rtc IRQ. - */ -static inline void -ds1685_rtc_end_ctrl_access(struct ds1685_priv *rtc, unsigned long flags) -{ - ds1685_rtc_switch_to_bank0(rtc); - spin_unlock_irqrestore(&rtc->lock, flags); -} - -/** * ds1685_rtc_get_ssn - retrieve the silicon serial number. * @rtc: pointer to the ds1685 rtc structure. * @ssn: u8 array to hold the bits of the silicon serial number. @@ -546,10 +510,6 @@ static int ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct ds1685_priv *rtc = dev_get_drvdata(dev); - unsigned long flags = 0; - - /* Enable/disable the Alarm IRQ-Enable flag. */ - spin_lock_irqsave(&rtc->lock, flags); /* Flip the requisite interrupt-enable bit. */ if (enabled) @@ -561,7 +521,6 @@ ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) /* Read Control C to clear all the flag bits. */ rtc->read(rtc, RTC_CTRL_C); - spin_unlock_irqrestore(&rtc->lock, flags); return 0; } @@ -569,98 +528,18 @@ ds1685_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) /* ----------------------------------------------------------------------- */ -/* IRQ handler & workqueue. */ - -/** - * ds1685_rtc_irq_handler - IRQ handler. - * @irq: IRQ number. - * @dev_id: platform device pointer. - */ -static irqreturn_t -ds1685_rtc_irq_handler(int irq, void *dev_id) -{ - struct platform_device *pdev = dev_id; - struct ds1685_priv *rtc = platform_get_drvdata(pdev); - u8 ctrlb, ctrlc; - unsigned long events = 0; - u8 num_irqs = 0; - - /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */ - if (unlikely(!rtc)) - return IRQ_HANDLED; - - /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ - spin_lock(&rtc->lock); - ctrlb = rtc->read(rtc, RTC_CTRL_B); - ctrlc = rtc->read(rtc, RTC_CTRL_C); - - /* Is the IRQF bit set? */ - if (likely(ctrlc & RTC_CTRL_C_IRQF)) { - /* - * We need to determine if it was one of the standard - * events: PF, AF, or UF. If so, we handle them and - * update the RTC core. - */ - if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) { - events = RTC_IRQF; - - /* Check for a periodic interrupt. */ - if ((ctrlb & RTC_CTRL_B_PIE) && - (ctrlc & RTC_CTRL_C_PF)) { - events |= RTC_PF; - num_irqs++; - } - - /* Check for an alarm interrupt. */ - if ((ctrlb & RTC_CTRL_B_AIE) && - (ctrlc & RTC_CTRL_C_AF)) { - events |= RTC_AF; - num_irqs++; - } - - /* Check for an update interrupt. */ - if ((ctrlb & RTC_CTRL_B_UIE) && - (ctrlc & RTC_CTRL_C_UF)) { - events |= RTC_UF; - num_irqs++; - } - - rtc_update_irq(rtc->dev, num_irqs, events); - } else { - /* - * One of the "extended" interrupts was received that - * is not recognized by the RTC core. These need to - * be handled in task context as they can call other - * functions and the time spent in irq context needs - * to be minimized. Schedule them into a workqueue - * and inform the RTC core that the IRQs were handled. - */ - spin_unlock(&rtc->lock); - schedule_work(&rtc->work); - rtc_update_irq(rtc->dev, 0, 0); - return IRQ_HANDLED; - } - } - spin_unlock(&rtc->lock); - - return events ? IRQ_HANDLED : IRQ_NONE; -} +/* IRQ handler */ /** - * ds1685_rtc_work_queue - work queue handler. - * @work: work_struct containing data to work on in task context. + * ds1685_rtc_extended_irq - take care of extended interrupts + * @rtc: pointer to the ds1685 rtc structure. + * @pdev: platform device pointer. */ static void -ds1685_rtc_work_queue(struct work_struct *work) +ds1685_rtc_extended_irq(struct ds1685_priv *rtc, struct platform_device *pdev) { - struct ds1685_priv *rtc = container_of(work, - struct ds1685_priv, work); - struct platform_device *pdev = to_platform_device(&rtc->dev->dev); - struct mutex *rtc_mutex = &rtc->dev->ops_lock; u8 ctrl4a, ctrl4b; - mutex_lock(rtc_mutex); - ds1685_rtc_switch_to_bank1(rtc); ctrl4a = rtc->read(rtc, RTC_EXT_CTRL_4A); ctrl4b = rtc->read(rtc, RTC_EXT_CTRL_4B); @@ -739,8 +618,76 @@ ds1685_rtc_work_queue(struct work_struct *work) "RAM-Clear IRQ just occurred!\n"); } ds1685_rtc_switch_to_bank0(rtc); +} + +/** + * ds1685_rtc_irq_handler - IRQ handler. + * @irq: IRQ number. + * @dev_id: platform device pointer. + */ +static irqreturn_t +ds1685_rtc_irq_handler(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct ds1685_priv *rtc = platform_get_drvdata(pdev); + struct mutex *rtc_mutex; + u8 ctrlb, ctrlc; + unsigned long events = 0; + u8 num_irqs = 0; + + /* Abort early if the device isn't ready yet (i.e., DEBUG_SHIRQ). */ + if (unlikely(!rtc)) + return IRQ_HANDLED; + + rtc_mutex = &rtc->dev->ops_lock; + mutex_lock(rtc_mutex); + /* Ctrlb holds the interrupt-enable bits and ctrlc the flag bits. */ + ctrlb = rtc->read(rtc, RTC_CTRL_B); + ctrlc = rtc->read(rtc, RTC_CTRL_C); + + /* Is the IRQF bit set? */ + if (likely(ctrlc & RTC_CTRL_C_IRQF)) { + /* + * We need to determine if it was one of the standard + * events: PF, AF, or UF. If so, we handle them and + * update the RTC core. + */ + if (likely(ctrlc & RTC_CTRL_B_PAU_MASK)) { + events = RTC_IRQF; + + /* Check for a periodic interrupt. */ + if ((ctrlb & RTC_CTRL_B_PIE) && + (ctrlc & RTC_CTRL_C_PF)) { + events |= RTC_PF; + num_irqs++; + } + + /* Check for an alarm interrupt. */ + if ((ctrlb & RTC_CTRL_B_AIE) && + (ctrlc & RTC_CTRL_C_AF)) { + events |= RTC_AF; + num_irqs++; + } + + /* Check for an update interrupt. */ + if ((ctrlb & RTC_CTRL_B_UIE) && + (ctrlc & RTC_CTRL_C_UF)) { + events |= RTC_UF; + num_irqs++; + } + } else { + /* + * One of the "extended" interrupts was received that + * is not recognized by the RTC core. + */ + ds1685_rtc_extended_irq(rtc, pdev); + } + } + rtc_update_irq(rtc->dev, num_irqs, events); mutex_unlock(rtc_mutex); + + return events ? IRQ_HANDLED : IRQ_NONE; } /* ----------------------------------------------------------------------- */ @@ -869,11 +816,15 @@ static int ds1685_nvram_read(void *priv, unsigned int pos, void *val, size_t size) { struct ds1685_priv *rtc = priv; + struct mutex *rtc_mutex = &rtc->dev->ops_lock; ssize_t count; - unsigned long flags = 0; u8 *buf = val; + int err; + + err = mutex_lock_interruptible(rtc_mutex); + if (err) + return err; - spin_lock_irqsave(&rtc->lock, flags); ds1685_rtc_switch_to_bank0(rtc); /* Read NVRAM in time and bank0 registers. */ @@ -923,7 +874,7 @@ static int ds1685_nvram_read(void *priv, unsigned int pos, void *val, ds1685_rtc_switch_to_bank0(rtc); } #endif /* !CONFIG_RTC_DRV_DS1689 */ - spin_unlock_irqrestore(&rtc->lock, flags); + mutex_unlock(rtc_mutex); return 0; } @@ -932,11 +883,15 @@ static int ds1685_nvram_write(void *priv, unsigned int pos, void *val, size_t size) { struct ds1685_priv *rtc = priv; + struct mutex *rtc_mutex = &rtc->dev->ops_lock; ssize_t count; - unsigned long flags = 0; u8 *buf = val; + int err; + + err = mutex_lock_interruptible(rtc_mutex); + if (err) + return err; - spin_lock_irqsave(&rtc->lock, flags); ds1685_rtc_switch_to_bank0(rtc); /* Write NVRAM in time and bank0 registers. */ @@ -986,7 +941,7 @@ static int ds1685_nvram_write(void *priv, unsigned int pos, void *val, ds1685_rtc_switch_to_bank0(rtc); } #endif /* !CONFIG_RTC_DRV_DS1689 */ - spin_unlock_irqrestore(&rtc->lock, flags); + mutex_unlock(rtc_mutex); return 0; } @@ -1004,7 +959,7 @@ static ssize_t ds1685_rtc_sysfs_battery_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ds1685_priv *rtc = dev_get_drvdata(dev); + struct ds1685_priv *rtc = dev_get_drvdata(dev->parent); u8 ctrld; ctrld = rtc->read(rtc, RTC_CTRL_D); @@ -1024,7 +979,7 @@ static ssize_t ds1685_rtc_sysfs_auxbatt_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ds1685_priv *rtc = dev_get_drvdata(dev); + struct ds1685_priv *rtc = dev_get_drvdata(dev->parent); u8 ctrl4a; ds1685_rtc_switch_to_bank1(rtc); @@ -1046,7 +1001,7 @@ static ssize_t ds1685_rtc_sysfs_serial_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct ds1685_priv *rtc = dev_get_drvdata(dev); + struct ds1685_priv *rtc = dev_get_drvdata(dev->parent); u8 ssn[8]; ds1685_rtc_switch_to_bank1(rtc); @@ -1177,9 +1132,7 @@ ds1685_rtc_probe(struct platform_device *pdev) if (pdata->plat_post_ram_clear) rtc->post_ram_clear = pdata->plat_post_ram_clear; - /* Init the spinlock, workqueue, & set the driver data. */ - spin_lock_init(&rtc->lock); - INIT_WORK(&rtc->work, ds1685_rtc_work_queue); + /* set the driver data. */ platform_set_drvdata(pdev, rtc); /* Turn the oscillator on if is not already on (DV1 = 1). */ @@ -1335,22 +1288,23 @@ ds1685_rtc_probe(struct platform_device *pdev) */ if (!pdata->no_irq) { ret = platform_get_irq(pdev, 0); - if (ret > 0) { - rtc->irq_num = ret; - - /* Request an IRQ. */ - ret = devm_request_irq(&pdev->dev, rtc->irq_num, - ds1685_rtc_irq_handler, - IRQF_SHARED, pdev->name, pdev); - - /* Check to see if something came back. */ - if (unlikely(ret)) { - dev_warn(&pdev->dev, - "RTC interrupt not available\n"); - rtc->irq_num = 0; - } - } else + if (ret <= 0) return ret; + + rtc->irq_num = ret; + + /* Request an IRQ. */ + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_num, + NULL, ds1685_rtc_irq_handler, + IRQF_SHARED | IRQF_ONESHOT, + pdev->name, pdev); + + /* Check to see if something came back. */ + if (unlikely(ret)) { + dev_warn(&pdev->dev, + "RTC interrupt not available\n"); + rtc->irq_num = 0; + } } rtc->no_irq = pdata->no_irq; @@ -1397,8 +1351,6 @@ ds1685_rtc_remove(struct platform_device *pdev) (rtc->read(rtc, RTC_EXT_CTRL_4A) & ~(RTC_CTRL_4A_RWK_MASK))); - cancel_work_sync(&rtc->work); - return 0; } diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index b886b6a5c178..1e9f429ada64 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c @@ -1,11 +1,5 @@ -/* - * Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> - * - * 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. - * - */ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2012 Sven Schnelle <svens@stackframe.org> #include <linux/platform_device.h> #include <linux/module.h> @@ -29,14 +23,6 @@ #define DS2404_COPY_SCRATCHPAD_CMD 0x55 #define DS2404_READ_MEMORY_CMD 0xf0 -struct ds2404; - -struct ds2404_chip_ops { - int (*map_io)(struct ds2404 *chip, struct platform_device *pdev, - struct ds2404_platform_data *pdata); - void (*unmap_io)(struct ds2404 *chip); -}; - #define DS2404_RST 0 #define DS2404_CLK 1 #define DS2404_DQ 2 @@ -48,7 +34,6 @@ struct ds2404_gpio { struct ds2404 { struct ds2404_gpio *gpio; - const struct ds2404_chip_ops *ops; struct rtc_device *rtc; }; @@ -87,7 +72,7 @@ err_request: return err; } -static void ds2404_gpio_unmap(struct ds2404 *chip) +static void ds2404_gpio_unmap(void *data) { int i; @@ -95,11 +80,6 @@ static void ds2404_gpio_unmap(struct ds2404 *chip) gpio_free(ds2404_gpio[i].gpio); } -static const struct ds2404_chip_ops ds2404_gpio_ops = { - .map_io = ds2404_gpio_map, - .unmap_io = ds2404_gpio_unmap, -}; - static void ds2404_reset(struct device *dev) { gpio_set_value(ds2404_gpio[DS2404_RST].gpio, 0); @@ -206,20 +186,20 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt) ds2404_read_memory(dev, 0x203, 4, (u8 *)&time); time = le32_to_cpu(time); - rtc_time_to_tm(time, dt); + rtc_time64_to_tm(time, dt); return 0; } -static int ds2404_set_mmss(struct device *dev, unsigned long secs) +static int ds2404_set_time(struct device *dev, struct rtc_time *dt) { - u32 time = cpu_to_le32(secs); + u32 time = cpu_to_le32(rtc_tm_to_time64(dt)); ds2404_write_memory(dev, 0x203, 4, (u8 *)&time); return 0; } static const struct rtc_class_ops ds2404_rtc_ops = { .read_time = ds2404_read_time, - .set_mmss = ds2404_set_mmss, + .set_time = ds2404_set_time, }; static int rtc_probe(struct platform_device *pdev) @@ -232,11 +212,17 @@ static int rtc_probe(struct platform_device *pdev) if (!chip) return -ENOMEM; - chip->ops = &ds2404_gpio_ops; + chip->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(chip->rtc)) + return PTR_ERR(chip->rtc); - retval = chip->ops->map_io(chip, pdev, pdata); + retval = ds2404_gpio_map(chip, pdev, pdata); if (retval) - goto err_chip; + return retval; + + retval = devm_add_action_or_reset(&pdev->dev, ds2404_gpio_unmap, chip); + if (retval) + return retval; dev_info(&pdev->dev, "using GPIOs RST:%d, CLK:%d, DQ:%d\n", chip->gpio[DS2404_RST].gpio, chip->gpio[DS2404_CLK].gpio, @@ -244,34 +230,19 @@ static int rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, chip); - chip->rtc = devm_rtc_device_register(&pdev->dev, "ds2404", - &ds2404_rtc_ops, THIS_MODULE); - if (IS_ERR(chip->rtc)) { - retval = PTR_ERR(chip->rtc); - goto err_io; - } + chip->rtc->ops = &ds2404_rtc_ops; + chip->rtc->range_max = U32_MAX; - ds2404_enable_osc(&pdev->dev); - return 0; - -err_io: - chip->ops->unmap_io(chip); -err_chip: - return retval; -} - -static int rtc_remove(struct platform_device *dev) -{ - struct ds2404 *chip = platform_get_drvdata(dev); - - chip->ops->unmap_io(chip); + retval = rtc_register_device(chip->rtc); + if (retval) + return retval; + ds2404_enable_osc(&pdev->dev); return 0; } static struct platform_driver rtc_device_driver = { .probe = rtc_probe, - .remove = rtc_remove, .driver = { .name = "ds2404", }, diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 7184e5145f12..1e9312f96021 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -48,6 +48,10 @@ # define DS3232_REG_SR_A1F 0x01 #define DS3232_REG_TEMPERATURE 0x11 +#define DS3232_REG_SRAM_START 0x14 +#define DS3232_REG_SRAM_END 0xFF + +#define DS3232_REG_SRAM_SIZE 236 struct ds3232 { struct device *dev; @@ -461,11 +465,39 @@ static const struct rtc_class_ops ds3232_rtc_ops = { .alarm_irq_enable = ds3232_alarm_irq_enable, }; +static int ds3232_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct regmap *ds3232_regmap = (struct regmap *)priv; + + return regmap_bulk_read(ds3232_regmap, DS3232_REG_SRAM_START + offset, + val, bytes); +} + +static int ds3232_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct regmap *ds3232_regmap = (struct regmap *)priv; + + return regmap_bulk_write(ds3232_regmap, DS3232_REG_SRAM_START + offset, + val, bytes); +} + static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, const char *name) { struct ds3232 *ds3232; int ret; + struct nvmem_config nvmem_cfg = { + .name = "ds3232_sram", + .stride = 1, + .size = DS3232_REG_SRAM_SIZE, + .word_size = 1, + .reg_read = ds3232_nvmem_read, + .reg_write = ds3232_nvmem_write, + .priv = regmap, + .type = NVMEM_TYPE_BATTERY_BACKED + }; ds3232 = devm_kzalloc(dev, sizeof(*ds3232), GFP_KERNEL); if (!ds3232) @@ -490,6 +522,10 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, if (IS_ERR(ds3232->rtc)) return PTR_ERR(ds3232->rtc); + ret = rtc_nvmem_register(ds3232->rtc, &nvmem_cfg); + if(ret) + return ret; + if (ds3232->irq > 0) { ret = devm_request_threaded_irq(dev, ds3232->irq, NULL, ds3232_irq, @@ -542,7 +578,7 @@ static int ds3232_i2c_probe(struct i2c_client *client, static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, - .max_register = 0x13, + .max_register = DS3232_REG_SRAM_END, }; regmap = devm_regmap_init_i2c(client, &config); @@ -609,7 +645,7 @@ static int ds3234_probe(struct spi_device *spi) static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, - .max_register = 0x13, + .max_register = DS3232_REG_SRAM_END, .write_flag_mask = 0x80, }; struct regmap *regmap; diff --git a/drivers/rtc/rtc-ep93xx.c b/drivers/rtc/rtc-ep93xx.c index 1932a4f861d1..1766496385fe 100644 --- a/drivers/rtc/rtc-ep93xx.c +++ b/drivers/rtc/rtc-ep93xx.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * A driver for the RTC embedded in the Cirrus Logic EP93XX processors * Copyright (c) 2006 Tower Technologies * * Author: Alessandro Zummo <a.zummo@towertech.it> - * - * 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. */ #include <linux/module.h> @@ -18,27 +15,23 @@ #define EP93XX_RTC_DATA 0x000 #define EP93XX_RTC_MATCH 0x004 #define EP93XX_RTC_STATUS 0x008 -#define EP93XX_RTC_STATUS_INTR (1<<0) +#define EP93XX_RTC_STATUS_INTR BIT(0) #define EP93XX_RTC_LOAD 0x00C #define EP93XX_RTC_CONTROL 0x010 -#define EP93XX_RTC_CONTROL_MIE (1<<0) +#define EP93XX_RTC_CONTROL_MIE BIT(0) #define EP93XX_RTC_SWCOMP 0x108 #define EP93XX_RTC_SWCOMP_DEL_MASK 0x001f0000 #define EP93XX_RTC_SWCOMP_DEL_SHIFT 16 #define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff #define EP93XX_RTC_SWCOMP_INT_SHIFT 0 -/* - * struct device dev.platform_data is used to store our private data - * because struct rtc_device does not have a variable to hold it. - */ struct ep93xx_rtc { void __iomem *mmio_base; struct rtc_device *rtc; }; static int ep93xx_rtc_get_swcomp(struct device *dev, unsigned short *preload, - unsigned short *delete) + unsigned short *delete) { struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); unsigned long comp; @@ -63,13 +56,14 @@ static int ep93xx_rtc_read_time(struct device *dev, struct rtc_time *tm) time = readl(ep93xx_rtc->mmio_base + EP93XX_RTC_DATA); - rtc_time_to_tm(time, tm); + rtc_time64_to_tm(time, tm); return 0; } -static int ep93xx_rtc_set_mmss(struct device *dev, unsigned long secs) +static int ep93xx_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct ep93xx_rtc *ep93xx_rtc = dev_get_platdata(dev); + unsigned long secs = rtc_tm_to_time64(tm); writel(secs + 1, ep93xx_rtc->mmio_base + EP93XX_RTC_LOAD); return 0; @@ -89,31 +83,31 @@ static int ep93xx_rtc_proc(struct device *dev, struct seq_file *seq) static const struct rtc_class_ops ep93xx_rtc_ops = { .read_time = ep93xx_rtc_read_time, - .set_mmss = ep93xx_rtc_set_mmss, + .set_time = ep93xx_rtc_set_time, .proc = ep93xx_rtc_proc, }; -static ssize_t ep93xx_rtc_show_comp_preload(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t comp_preload_show(struct device *dev, + struct device_attribute *attr, char *buf) { unsigned short preload; - ep93xx_rtc_get_swcomp(dev, &preload, NULL); + ep93xx_rtc_get_swcomp(dev->parent, &preload, NULL); return sprintf(buf, "%d\n", preload); } -static DEVICE_ATTR(comp_preload, S_IRUGO, ep93xx_rtc_show_comp_preload, NULL); +static DEVICE_ATTR_RO(comp_preload); -static ssize_t ep93xx_rtc_show_comp_delete(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t comp_delete_show(struct device *dev, + struct device_attribute *attr, char *buf) { unsigned short delete; - ep93xx_rtc_get_swcomp(dev, NULL, &delete); + ep93xx_rtc_get_swcomp(dev->parent, NULL, &delete); return sprintf(buf, "%d\n", delete); } -static DEVICE_ATTR(comp_delete, S_IRUGO, ep93xx_rtc_show_comp_delete, NULL); +static DEVICE_ATTR_RO(comp_delete); static struct attribute *ep93xx_rtc_attrs[] = { &dev_attr_comp_preload.attr, @@ -140,33 +134,20 @@ static int ep93xx_rtc_probe(struct platform_device *pdev) if (IS_ERR(ep93xx_rtc->mmio_base)) return PTR_ERR(ep93xx_rtc->mmio_base); - pdev->dev.platform_data = ep93xx_rtc; platform_set_drvdata(pdev, ep93xx_rtc); - ep93xx_rtc->rtc = devm_rtc_device_register(&pdev->dev, - pdev->name, &ep93xx_rtc_ops, THIS_MODULE); - if (IS_ERR(ep93xx_rtc->rtc)) { - err = PTR_ERR(ep93xx_rtc->rtc); - goto exit; - } + ep93xx_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(ep93xx_rtc->rtc)) + return PTR_ERR(ep93xx_rtc->rtc); - err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); - if (err) - goto exit; - - return 0; + ep93xx_rtc->rtc->ops = &ep93xx_rtc_ops; + ep93xx_rtc->rtc->range_max = U32_MAX; -exit: - pdev->dev.platform_data = NULL; - return err; -} - -static int ep93xx_rtc_remove(struct platform_device *pdev) -{ - sysfs_remove_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); - pdev->dev.platform_data = NULL; + err = rtc_add_group(ep93xx_rtc->rtc, &ep93xx_rtc_sysfs_files); + if (err) + return err; - return 0; + return rtc_register_device(ep93xx_rtc->rtc); } static struct platform_driver ep93xx_rtc_driver = { @@ -174,7 +155,6 @@ static struct platform_driver ep93xx_rtc_driver = { .name = "ep93xx-rtc", }, .probe = ep93xx_rtc_probe, - .remove = ep93xx_rtc_remove, }; module_platform_driver(ep93xx_rtc_driver); diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c index a1c44d0c8557..1a3420ee6a4d 100644 --- a/drivers/rtc/rtc-goldfish.c +++ b/drivers/rtc/rtc-goldfish.c @@ -1,23 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 /* drivers/rtc/rtc-goldfish.c * * Copyright (C) 2007 Google, Inc. * Copyright (C) 2017 Imagination Technologies Ltd. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ +#include <linux/io.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/rtc.h> -#include <linux/io.h> #define TIMER_TIME_LOW 0x00 /* get low bits of current time */ /* and update TIMER_TIME_HIGH */ @@ -56,7 +48,7 @@ static int goldfish_rtc_read_alarm(struct device *dev, do_div(rtc_alarm, NSEC_PER_SEC); memset(alrm, 0, sizeof(struct rtc_wkalrm)); - rtc_time_to_tm(rtc_alarm, &alrm->time); + rtc_time64_to_tm(rtc_alarm, &alrm->time); if (readl(base + TIMER_ALARM_STATUS)) alrm->enabled = 1; @@ -70,21 +62,15 @@ static int goldfish_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct goldfish_rtc *rtcdrv; - unsigned long rtc_alarm; u64 rtc_alarm64; u64 rtc_status_reg; void __iomem *base; - int ret = 0; rtcdrv = dev_get_drvdata(dev); base = rtcdrv->base; if (alrm->enabled) { - ret = rtc_tm_to_time(&alrm->time, &rtc_alarm); - if (ret != 0) - return ret; - - rtc_alarm64 = rtc_alarm * NSEC_PER_SEC; + rtc_alarm64 = rtc_tm_to_time64(&alrm->time) * NSEC_PER_SEC; writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH); writel(rtc_alarm64, base + TIMER_ALARM_LOW); } else { @@ -98,7 +84,7 @@ static int goldfish_rtc_set_alarm(struct device *dev, writel(1, base + TIMER_CLEAR_ALARM); } - return ret; + return 0; } static int goldfish_rtc_alarm_irq_enable(struct device *dev, @@ -147,7 +133,7 @@ static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm) do_div(time, NSEC_PER_SEC); - rtc_time_to_tm(time, tm); + rtc_time64_to_tm(time, tm); return 0; } @@ -156,21 +142,16 @@ static int goldfish_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct goldfish_rtc *rtcdrv; void __iomem *base; - unsigned long now; u64 now64; - int ret; rtcdrv = dev_get_drvdata(dev); base = rtcdrv->base; - ret = rtc_tm_to_time(tm, &now); - if (ret == 0) { - now64 = now * NSEC_PER_SEC; - writel((now64 >> 32), base + TIMER_TIME_HIGH); - writel(now64, base + TIMER_TIME_LOW); - } + now64 = rtc_tm_to_time64(tm) * NSEC_PER_SEC; + writel((now64 >> 32), base + TIMER_TIME_HIGH); + writel(now64, base + TIMER_TIME_LOW); - return ret; + return 0; } static const struct rtc_class_ops goldfish_rtc_ops = { @@ -205,19 +186,20 @@ static int goldfish_rtc_probe(struct platform_device *pdev) if (rtcdrv->irq < 0) return -ENODEV; - rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &goldfish_rtc_ops, - THIS_MODULE); + rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtcdrv->rtc)) return PTR_ERR(rtcdrv->rtc); + rtcdrv->rtc->ops = &goldfish_rtc_ops; + rtcdrv->rtc->range_max = U64_MAX / NSEC_PER_SEC; + err = devm_request_irq(&pdev->dev, rtcdrv->irq, goldfish_rtc_interrupt, 0, pdev->name, rtcdrv); if (err) return err; - return 0; + return rtc_register_device(rtcdrv->rtc); } static const struct of_device_id goldfish_rtc_of_match[] = { diff --git a/drivers/rtc/rtc-hid-sensor-time.c b/drivers/rtc/rtc-hid-sensor-time.c index 3e1abb455472..f27c40e8331f 100644 --- a/drivers/rtc/rtc-hid-sensor-time.c +++ b/drivers/rtc/rtc-hid-sensor-time.c @@ -205,8 +205,7 @@ static int hid_time_parse_report(struct platform_device *pdev, static int hid_rtc_read_time(struct device *dev, struct rtc_time *tm) { unsigned long flags; - struct hid_time_state *time_state = - platform_get_drvdata(to_platform_device(dev)); + struct hid_time_state *time_state = dev_get_drvdata(dev); int ret; reinit_completion(&time_state->comp_last_time); diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 80931114c899..3f3d652a0b0f 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -1,20 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2010 Orex Computed Radiography */ /* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/* based on rtc-mc13892.c */ - -/* * This driver uses the 47-bit 32 kHz counter in the Freescale DryIce block * to implement a Linux RTC. Times and alarms are truncated to seconds. * Since the RTC framework performs API locking via rtc->ops_lock the @@ -552,7 +542,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm) unsigned long now; now = readl(imxdi->ioaddr + DTCMR); - rtc_time_to_tm(now, tm); + rtc_time64_to_tm(now, tm); return 0; } @@ -561,7 +551,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm) * set the seconds portion of dryice time counter and clear the * fractional part. */ -static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs) +static int dryice_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct imxdi_dev *imxdi = dev_get_drvdata(dev); u32 dcr, dsr; @@ -588,7 +578,7 @@ static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs) if (rc != 0) return rc; - rc = di_write_wait(imxdi, secs, DTCMR); + rc = di_write_wait(imxdi, rtc_tm_to_time64(tm), DTCMR); if (rc != 0) return rc; @@ -618,7 +608,7 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) u32 dcamr; dcamr = readl(imxdi->ioaddr + DCAMR); - rtc_time_to_tm(dcamr, &alarm->time); + rtc_time64_to_tm(dcamr, &alarm->time); /* alarm is enabled if the interrupt is enabled */ alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0; @@ -640,21 +630,10 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct imxdi_dev *imxdi = dev_get_drvdata(dev); - unsigned long now; - unsigned long alarm_time; int rc; - rc = rtc_tm_to_time(&alarm->time, &alarm_time); - if (rc) - return rc; - - /* don't allow setting alarm in the past */ - now = readl(imxdi->ioaddr + DTCMR); - if (alarm_time < now) - return -EINVAL; - /* write the new alarm time */ - rc = di_write_wait(imxdi, (u32)alarm_time, DCAMR); + rc = di_write_wait(imxdi, rtc_tm_to_time64(&alarm->time), DCAMR); if (rc) return rc; @@ -668,7 +647,7 @@ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) static const struct rtc_class_ops dryice_rtc_ops = { .read_time = dryice_rtc_read_time, - .set_mmss = dryice_rtc_set_mmss, + .set_time = dryice_rtc_set_time, .alarm_irq_enable = dryice_rtc_alarm_irq_enable, .read_alarm = dryice_rtc_read_alarm, .set_alarm = dryice_rtc_set_alarm, @@ -796,6 +775,10 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) mutex_init(&imxdi->write_mutex); + imxdi->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(imxdi->rtc)) + return PTR_ERR(imxdi->rtc); + imxdi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(imxdi->clk)) return PTR_ERR(imxdi->clk); @@ -829,12 +812,13 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, imxdi); - imxdi->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &dryice_rtc_ops, THIS_MODULE); - if (IS_ERR(imxdi->rtc)) { - rc = PTR_ERR(imxdi->rtc); + + imxdi->rtc->ops = &dryice_rtc_ops; + imxdi->rtc->range_max = U32_MAX; + + rc = rtc_register_device(imxdi->rtc); + if (rc) goto err; - } return 0; diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index d0a891777f44..9e7b3a04debc 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -1,17 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> * Copyright (C) 2010, Paul Cercueil <paul@crapouillou.net> * JZ4740 SoC RTC driver - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * */ #include <linux/clk.h> @@ -20,6 +11,7 @@ #include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/reboot.h> #include <linux/rtc.h> #include <linux/slab.h> @@ -156,6 +148,9 @@ static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) uint32_t secs, secs2; int timeout = 5; + if (jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD) != 0x12345678) + return -EINVAL; + /* If the seconds register is read while it is updated, it can contain a * bogus value. This can be avoided by making sure that two consecutive * reads have the same value. @@ -171,16 +166,21 @@ static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) if (timeout == 0) return -EIO; - rtc_time_to_tm(secs, time); + rtc_time64_to_tm(secs, time); return 0; } -static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs) +static int jz4740_rtc_set_time(struct device *dev, struct rtc_time *time) { struct jz4740_rtc *rtc = dev_get_drvdata(dev); + int ret; - return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, secs); + ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, rtc_tm_to_time64(time)); + if (ret) + return ret; + + return jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); } static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -196,18 +196,16 @@ static int jz4740_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->enabled = !!(ctrl & JZ_RTC_CTRL_AE); alrm->pending = !!(ctrl & JZ_RTC_CTRL_AF); - rtc_time_to_tm(secs, &alrm->time); + rtc_time64_to_tm(secs, &alrm->time); - return rtc_valid_tm(&alrm->time); + return 0; } static int jz4740_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { int ret; struct jz4740_rtc *rtc = dev_get_drvdata(dev); - unsigned long secs; - - rtc_tm_to_time(&alrm->time, &secs); + uint32_t secs = lower_32_bits(rtc_tm_to_time64(&alrm->time)); ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC_ALARM, secs); if (!ret) @@ -225,7 +223,7 @@ static int jz4740_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) static const struct rtc_class_ops jz4740_rtc_ops = { .read_time = jz4740_rtc_read_time, - .set_mmss = jz4740_rtc_set_mmss, + .set_time = jz4740_rtc_set_time, .read_alarm = jz4740_rtc_read_alarm, .set_alarm = jz4740_rtc_set_alarm, .alarm_irq_enable = jz4740_rtc_alarm_irq_enable, @@ -309,7 +307,6 @@ static int jz4740_rtc_probe(struct platform_device *pdev) { int ret; struct jz4740_rtc *rtc; - uint32_t scratchpad; struct resource *mem; const struct platform_device_id *id = platform_get_device_id(pdev); const struct of_device_id *of_id = of_match_device( @@ -348,10 +345,24 @@ static int jz4740_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &jz4740_rtc_ops, THIS_MODULE); + ret = dev_pm_set_wake_irq(&pdev->dev, rtc->irq); + if (ret) { + dev_err(&pdev->dev, "Failed to set wake irq: %d\n", ret); + return ret; + } + + rtc->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtc)) { ret = PTR_ERR(rtc->rtc); + dev_err(&pdev->dev, "Failed to allocate rtc device: %d\n", ret); + return ret; + } + + rtc->rtc->ops = &jz4740_rtc_ops; + rtc->rtc->range_max = U32_MAX; + + ret = rtc_register_device(rtc->rtc); + if (ret) { dev_err(&pdev->dev, "Failed to register rtc device: %d\n", ret); return ret; } @@ -363,16 +374,6 @@ static int jz4740_rtc_probe(struct platform_device *pdev) return ret; } - scratchpad = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD); - if (scratchpad != 0x12345678) { - ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SCRATCHPAD, 0x12345678); - ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_SEC, 0); - if (ret) { - dev_err(&pdev->dev, "Could not write to RTC registers\n"); - return ret; - } - } - if (np && of_device_is_system_power_controller(np)) { if (!pm_power_off) { /* Default: 60ms */ @@ -397,35 +398,6 @@ static int jz4740_rtc_probe(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int jz4740_rtc_suspend(struct device *dev) -{ - struct jz4740_rtc *rtc = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(rtc->irq); - return 0; -} - -static int jz4740_rtc_resume(struct device *dev) -{ - struct jz4740_rtc *rtc = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(rtc->irq); - return 0; -} - -static const struct dev_pm_ops jz4740_pm_ops = { - .suspend = jz4740_rtc_suspend, - .resume = jz4740_rtc_resume, -}; -#define JZ4740_RTC_PM_OPS (&jz4740_pm_ops) - -#else -#define JZ4740_RTC_PM_OPS NULL -#endif /* CONFIG_PM */ - static const struct platform_device_id jz4740_rtc_ids[] = { { "jz4740-rtc", ID_JZ4740 }, { "jz4780-rtc", ID_JZ4780 }, @@ -437,7 +409,6 @@ static struct platform_driver jz4740_rtc_driver = { .probe = jz4740_rtc_probe, .driver = { .name = "jz4740-rtc", - .pm = JZ4740_RTC_PM_OPS, .of_match_table = of_match_ptr(jz4740_rtc_of_match), }, .id_table = jz4740_rtc_ids, diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index 910e600275b9..ac393230e592 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2010 NXP Semiconductors - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <linux/kernel.h> @@ -47,8 +39,6 @@ #define LPC32XX_RTC_KEY_ONSW_LOADVAL 0xB5C13F27 -#define RTC_NAME "rtc-lpc32xx" - #define rtc_readl(dev, reg) \ __raw_readl((dev)->rtc_base + (reg)) #define rtc_writel(dev, reg, val) \ @@ -68,14 +58,15 @@ static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); - rtc_time_to_tm(elapsed_sec, time); + rtc_time64_to_tm(elapsed_sec, time); return 0; } -static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) +static int lpc32xx_rtc_set_time(struct device *dev, struct rtc_time *time) { struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); + u32 secs = rtc_tm_to_time64(time); u32 tmp; spin_lock_irq(&rtc->lock); @@ -97,7 +88,7 @@ static int lpc32xx_rtc_read_alarm(struct device *dev, { struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); - rtc_time_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); + rtc_time64_to_tm(rtc_readl(rtc, LPC32XX_RTC_MATCH0), &wkalrm->time); wkalrm->enabled = rtc->alarm_enabled; wkalrm->pending = !!(rtc_readl(rtc, LPC32XX_RTC_INTSTAT) & LPC32XX_RTC_INTSTAT_MATCH0); @@ -111,13 +102,8 @@ static int lpc32xx_rtc_set_alarm(struct device *dev, struct lpc32xx_rtc *rtc = dev_get_drvdata(dev); unsigned long alarmsecs; u32 tmp; - int ret; - ret = rtc_tm_to_time(&wkalrm->time, &alarmsecs); - if (ret < 0) { - dev_warn(dev, "Failed to convert time: %d\n", ret); - return ret; - } + alarmsecs = rtc_tm_to_time64(&wkalrm->time); spin_lock_irq(&rtc->lock); @@ -191,7 +177,7 @@ static irqreturn_t lpc32xx_rtc_alarm_interrupt(int irq, void *dev) static const struct rtc_class_ops lpc32xx_rtc_ops = { .read_time = lpc32xx_rtc_read_time, - .set_mmss = lpc32xx_rtc_set_mmss, + .set_time = lpc32xx_rtc_set_time, .read_alarm = lpc32xx_rtc_read_alarm, .set_alarm = lpc32xx_rtc_set_alarm, .alarm_irq_enable = lpc32xx_rtc_alarm_irq_enable, @@ -201,21 +187,13 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) { struct resource *res; struct lpc32xx_rtc *rtc; - int rtcirq; + int err; u32 tmp; - rtcirq = platform_get_irq(pdev, 0); - if (rtcirq < 0) { - dev_warn(&pdev->dev, "Can't get interrupt resource\n"); - rtcirq = -1; - } - rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); if (unlikely(!rtc)) return -ENOMEM; - rtc->irq = rtcirq; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc->rtc_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rtc->rtc_base)) @@ -256,18 +234,25 @@ static int lpc32xx_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - rtc->rtc = devm_rtc_device_register(&pdev->dev, RTC_NAME, - &lpc32xx_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc->rtc)) { - dev_err(&pdev->dev, "Can't get RTC\n"); + rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc)) return PTR_ERR(rtc->rtc); - } + + rtc->rtc->ops = &lpc32xx_rtc_ops; + rtc->rtc->range_max = U32_MAX; + + err = rtc_register_device(rtc->rtc); + if (err) + return err; /* * IRQ is enabled after device registration in case alarm IRQ * is pending upon suspend exit. */ - if (rtc->irq >= 0) { + rtc->irq = platform_get_irq(pdev, 0); + if (rtc->irq < 0) { + dev_warn(&pdev->dev, "Can't get interrupt resource\n"); + } else { if (devm_request_irq(&pdev->dev, rtc->irq, lpc32xx_rtc_alarm_interrupt, 0, pdev->name, rtc) < 0) { @@ -374,7 +359,7 @@ static struct platform_driver lpc32xx_rtc_driver = { .probe = lpc32xx_rtc_probe, .remove = lpc32xx_rtc_remove, .driver = { - .name = RTC_NAME, + .name = "rtc-lpc32xx", .pm = LPC32XX_RTC_PM_OPS, .of_match_table = of_match_ptr(lpc32xx_rtc_match), }, diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 0fa33708fc49..afce2c0b4bd6 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Real Time Clock driver for Freescale MC13XXX PMIC * * (C) 2009 Sascha Hauer, Pengutronix * (C) 2009 Uwe Kleine-Koenig, Pengutronix - * - * 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. */ #include <linux/mfd/mc13xxx.h> @@ -89,14 +86,14 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) return 0; } -static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs) +static int mc13xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct mc13xxx_rtc *priv = dev_get_drvdata(dev); unsigned int seconds, days; unsigned int alarmseconds; int ret; - days = div_s64_rem(secs, SEC_PER_DAY, &seconds); + days = div_s64_rem(rtc_tm_to_time64(tm), SEC_PER_DAY, &seconds); mc13xxx_lock(priv->mc13xxx); @@ -158,7 +155,7 @@ out: 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 int seconds, days; time64_t s1970; int enabled, pending; int ret; @@ -253,7 +250,7 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev) static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_time = mc13xxx_rtc_read_time, - .set_mmss64 = mc13xxx_rtc_set_mmss, + .set_time = mc13xxx_rtc_set_time, .read_alarm = mc13xxx_rtc_read_alarm, .set_alarm = mc13xxx_rtc_set_alarm, .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable, @@ -285,8 +282,15 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) priv->mc13xxx = mc13xxx; priv->valid = 1; + priv->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(priv->rtc)) + return PTR_ERR(priv->rtc); platform_set_drvdata(pdev, priv); + priv->rtc->ops = &mc13xxx_rtc_ops; + /* 15bit days + hours, minutes, seconds */ + priv->rtc->range_max = (timeu64_t)(1 << 15) * SEC_PER_DAY - 1; + mc13xxx_lock(mc13xxx); mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_RTCRST); @@ -303,8 +307,9 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev) mc13xxx_unlock(mc13xxx); - priv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &mc13xxx_rtc_ops, THIS_MODULE); + ret = rtc_register_device(priv->rtc); + if (ret) + goto err_irq_request; return 0; diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index e9a25ec4d434..c06cf5202e02 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c @@ -343,7 +343,7 @@ static int mtk_rtc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", rtc->irq, ret); - goto out_dispose_irq; + return ret; } device_init_wakeup(&pdev->dev, 1); @@ -359,9 +359,7 @@ static int mtk_rtc_probe(struct platform_device *pdev) return 0; out_free_irq: - free_irq(rtc->irq, rtc->rtc_dev); -out_dispose_irq: - irq_dispose_mapping(rtc->irq); + free_irq(rtc->irq, rtc); return ret; } @@ -369,8 +367,7 @@ static int mtk_rtc_remove(struct platform_device *pdev) { struct mt6397_rtc *rtc = platform_get_drvdata(pdev); - free_irq(rtc->irq, rtc->rtc_dev); - irq_dispose_mapping(rtc->irq); + free_irq(rtc->irq, rtc); return 0; } diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index e7f14bd12fe3..ab9db57a6834 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -1,9 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for the RTC in Marvell SoCs. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #include <linux/init.h> @@ -60,7 +57,7 @@ static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm) rtc_reg = (bin2bcd(tm->tm_mday) << RTC_MDAY_OFFS) | (bin2bcd(tm->tm_mon + 1) << RTC_MONTH_OFFS) | - (bin2bcd(tm->tm_year % 100) << RTC_YEAR_OFFS); + (bin2bcd(tm->tm_year - 100) << RTC_YEAR_OFFS); writel(rtc_reg, ioaddr + RTC_DATE_REG_OFFS); return 0; @@ -159,7 +156,7 @@ static int mv_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) << RTC_MONTH_OFFS; if (alm->time.tm_year >= 0) - rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_year % 100)) + rtc_reg |= (RTC_ALARM_VALID | bin2bcd(alm->time.tm_year - 100)) << RTC_YEAR_OFFS; writel(rtc_reg, ioaddr + RTC_ALARM_DATE_REG_OFFS); @@ -257,15 +254,7 @@ static int __init mv_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pdata); - if (pdata->irq >= 0) { - device_init_wakeup(&pdev->dev, 1); - pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &mv_rtc_alarm_ops, - THIS_MODULE); - } else { - pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &mv_rtc_ops, THIS_MODULE); - } + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(pdata->rtc)) { ret = PTR_ERR(pdata->rtc); goto out; @@ -281,7 +270,19 @@ static int __init mv_rtc_probe(struct platform_device *pdev) } } - return 0; + if (pdata->irq >= 0) { + device_init_wakeup(&pdev->dev, 1); + pdata->rtc->ops = &mv_rtc_alarm_ops; + } else { + pdata->rtc->ops = &mv_rtc_ops; + } + + pdata->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + pdata->rtc->range_max = RTC_TIMESTAMP_END_2099; + + ret = rtc_register_device(pdata->rtc); + if (!ret) + return 0; out: if (!IS_ERR(pdata->clk)) clk_disable_unprepare(pdata->clk); diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 878c6ee82901..e697e96612bb 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -8,6 +8,7 @@ #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/clk.h> #include <linux/of.h> #include <linux/of_device.h> @@ -253,20 +254,9 @@ 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, time64_t time) +static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct rtc_plat_data *pdata = dev_get_drvdata(dev); - - /* - * TTC_DAYR register is 9-bit in MX1 SoC, save time and day of year only - */ - if (is_imx1_rtc(pdata)) { - struct rtc_time tm; - - rtc_time64_to_tm(time, &tm); - tm.tm_year = 70; - time = rtc_tm_to_time64(&tm); - } + time64_t time = rtc_tm_to_time64(tm); /* Avoid roll-over from reading the different registers */ do { @@ -310,7 +300,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) /* RTC layer */ static const struct rtc_class_ops mxc_rtc_ops = { .read_time = mxc_rtc_read_time, - .set_mmss64 = mxc_rtc_set_mmss, + .set_time = mxc_rtc_set_time, .read_alarm = mxc_rtc_read_alarm, .set_alarm = mxc_rtc_set_alarm, .alarm_irq_enable = mxc_rtc_alarm_irq_enable, @@ -318,7 +308,6 @@ static const struct rtc_class_ops mxc_rtc_ops = { static int mxc_rtc_probe(struct platform_device *pdev) { - struct resource *res; struct rtc_device *rtc; struct rtc_plat_data *pdata = NULL; u32 reg; @@ -336,11 +325,34 @@ static int mxc_rtc_probe(struct platform_device *pdev) else pdata->devtype = pdev->id_entry->driver_data; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res); + pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pdata->ioaddr)) return PTR_ERR(pdata->ioaddr); + rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); + + pdata->rtc = rtc; + rtc->ops = &mxc_rtc_ops; + if (is_imx1_rtc(pdata)) { + struct rtc_time tm; + + /* 9bit days + hours minutes seconds */ + rtc->range_max = (1 << 9) * 86400 - 1; + + /* + * Set the start date as beginning of the current year. This can + * be overridden using device tree. + */ + rtc_time64_to_tm(ktime_get_real_seconds(), &tm); + rtc->start_secs = mktime64(tm.tm_year, 1, 1, 0, 0, 0); + rtc->set_start_time = true; + } else { + /* 16bit days + hours minutes seconds */ + rtc->range_max = (1 << 16) * 86400ULL - 1; + } + pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); if (IS_ERR(pdata->clk_ipg)) { dev_err(&pdev->dev, "unable to get ipg clock!\n"); @@ -396,17 +408,16 @@ static int mxc_rtc_probe(struct platform_device *pdev) pdata->irq = -1; } - if (pdata->irq >= 0) + if (pdata->irq >= 0) { device_init_wakeup(&pdev->dev, 1); - - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto exit_put_clk_ref; + ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq); + if (ret) + dev_err(&pdev->dev, "failed to enable irq wake\n"); } - pdata->rtc = rtc; + ret = rtc_register_device(rtc); + if (ret) + goto exit_put_clk_ref; return 0; @@ -428,35 +439,10 @@ static int mxc_rtc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int mxc_rtc_suspend(struct device *dev) -{ - struct rtc_plat_data *pdata = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(pdata->irq); - - return 0; -} - -static int mxc_rtc_resume(struct device *dev) -{ - struct rtc_plat_data *pdata = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(pdata->irq); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume); - static struct platform_driver mxc_rtc_driver = { .driver = { .name = "mxc_rtc", .of_match_table = of_match_ptr(imx_rtc_dt_ids), - .pm = &mxc_rtc_pm_ops, }, .id_table = imx_rtc_devtype, .probe = mxc_rtc_probe, diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c index 007879a5042d..5b970a816631 100644 --- a/drivers/rtc/rtc-mxc_v2.c +++ b/drivers/rtc/rtc-mxc_v2.c @@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/rtc.h> #define SRTC_LPPDR_INIT 0x41736166 /* init for glitch detect */ @@ -305,6 +306,9 @@ static int mxc_rtc_probe(struct platform_device *pdev) return pdata->irq; device_init_wakeup(&pdev->dev, 1); + ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq); + if (ret) + dev_err(&pdev->dev, "failed to enable irq wake\n"); ret = clk_prepare_enable(pdata->clk); if (ret) @@ -367,30 +371,6 @@ static int mxc_rtc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int mxc_rtc_suspend(struct device *dev) -{ - struct mxc_rtc_data *pdata = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - enable_irq_wake(pdata->irq); - - return 0; -} - -static int mxc_rtc_resume(struct device *dev) -{ - struct mxc_rtc_data *pdata = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - disable_irq_wake(pdata->irq); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume); - static const struct of_device_id mxc_ids[] = { { .compatible = "fsl,imx53-rtc", }, {} @@ -400,7 +380,6 @@ static struct platform_driver mxc_rtc_driver = { .driver = { .name = "mxc_rtc_v2", .of_match_table = mxc_ids, - .pm = &mxc_rtc_pm_ops, }, .probe = mxc_rtc_probe, .remove = mxc_rtc_remove, diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index bbff0e2deb84..32994b0dd139 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * TI OMAP Real Time Clock interface for Linux * @@ -6,11 +7,6 @@ * * Copyright (C) 2006 David Brownell (new RTC framework) * Copyright (C) 2014 Johan Hovold <johan@kernel.org> - * - * 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 <dt-bindings/gpio/gpio.h> @@ -271,7 +267,7 @@ static int omap_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) } /* this hardware doesn't support "don't care" alarm fields */ -static int tm2bcd(struct rtc_time *tm) +static void tm2bcd(struct rtc_time *tm) { tm->tm_sec = bin2bcd(tm->tm_sec); tm->tm_min = bin2bcd(tm->tm_min); @@ -279,13 +275,7 @@ static int tm2bcd(struct rtc_time *tm) tm->tm_mday = bin2bcd(tm->tm_mday); tm->tm_mon = bin2bcd(tm->tm_mon + 1); - - /* epoch == 1900 */ - if (tm->tm_year < 100 || tm->tm_year > 199) - return -EINVAL; tm->tm_year = bin2bcd(tm->tm_year - 100); - - return 0; } static void bcd2tm(struct rtc_time *tm) @@ -328,8 +318,7 @@ static int omap_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct omap_rtc *rtc = dev_get_drvdata(dev); - if (tm2bcd(tm) < 0) - return -EINVAL; + tm2bcd(tm); local_irq_disable(); rtc_wait_not_busy(rtc); @@ -378,8 +367,7 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) struct omap_rtc *rtc = dev_get_drvdata(dev); u8 reg, irqwake_reg = 0; - if (tm2bcd(&alm->time) < 0) - return -EINVAL; + tm2bcd(&alm->time); local_irq_disable(); rtc_wait_not_busy(rtc); @@ -441,14 +429,10 @@ again: omap_rtc_read_time_raw(rtc, &tm); seconds = tm.tm_sec; bcd2tm(&tm); - rtc_tm_to_time(&tm, &now); - rtc_time_to_tm(now + 1, &tm); + now = rtc_tm_to_time64(&tm); + rtc_time64_to_tm(now + 1, &tm); - if (tm2bcd(&tm) < 0) { - dev_err(&rtc->rtc->dev, "power off failed\n"); - rtc->type->lock(rtc); - return; - } + tm2bcd(&tm); rtc_wait_not_busy(rtc); @@ -845,6 +829,8 @@ static int omap_rtc_probe(struct platform_device *pdev) } rtc->rtc->ops = &omap_rtc_ops; + rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->rtc->range_max = RTC_TIMESTAMP_END_2099; omap_rtc_nvmem_config.priv = rtc; /* handle periodic and alarm irqs */ diff --git a/drivers/rtc/rtc-opal.c b/drivers/rtc/rtc-opal.c index 60f2250fd96b..3dd9d266ce09 100644 --- a/drivers/rtc/rtc-opal.c +++ b/drivers/rtc/rtc-opal.c @@ -224,7 +224,7 @@ exit: return rc; } -int opal_tpo_alarm_irq_enable(struct device *dev, unsigned int enabled) +static int opal_tpo_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct rtc_wkalrm alarm = { .enabled = 0 }; diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index f176cb9d0dbc..178bfb1dea21 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * pcap rtc code for Motorola EZX phones * @@ -5,11 +6,6 @@ * Copyright (c) 2009 Daniel Ribeiro <drwyrm@gmail.com> * * Based on Motorola's rtc.c Copyright (c) 2003-2005 Motorola - * - * 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. - * */ #include <linux/kernel.h> @@ -55,7 +51,7 @@ static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAYA, &days); secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY; - rtc_time_to_tm(secs, tm); + rtc_time64_to_tm(secs, tm); return 0; } @@ -63,12 +59,9 @@ static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int pcap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev); - struct rtc_time *tm = &alrm->time; - unsigned long secs; + unsigned long secs = rtc_tm_to_time64(&alrm->time); u32 tod, days; - rtc_tm_to_time(tm, &secs); - tod = secs % SEC_PER_DAY; ezx_pcap_write(pcap_rtc->pcap, PCAP_REG_RTC_TODA, tod); @@ -90,14 +83,15 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm) ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAY, &days); secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY; - rtc_time_to_tm(secs, tm); + rtc_time64_to_tm(secs, tm); return 0; } -static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs) +static int pcap_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev); + unsigned long secs = rtc_tm_to_time64(tm); u32 tod, days; tod = secs % SEC_PER_DAY; @@ -128,9 +122,9 @@ static int pcap_rtc_alarm_irq_enable(struct device *dev, unsigned int en) static const struct rtc_class_ops pcap_rtc_ops = { .read_time = pcap_rtc_read_time, + .set_time = pcap_rtc_set_time, .read_alarm = pcap_rtc_read_alarm, .set_alarm = pcap_rtc_set_alarm, - .set_mmss = pcap_rtc_set_mmss, .alarm_irq_enable = pcap_rtc_alarm_irq_enable, }; @@ -149,11 +143,13 @@ static int __init pcap_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, pcap_rtc); - pcap_rtc->rtc = devm_rtc_device_register(&pdev->dev, "pcap", - &pcap_rtc_ops, THIS_MODULE); + pcap_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(pcap_rtc->rtc)) return PTR_ERR(pcap_rtc->rtc); + pcap_rtc->rtc->ops = &pcap_rtc_ops; + pcap_rtc->rtc->range_max = (1 << 14) * 86400ULL - 1; + timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); @@ -167,7 +163,7 @@ static int __init pcap_rtc_probe(struct platform_device *pdev) if (err) return err; - return 0; + return rtc_register_device(pcap_rtc->rtc); } static int __exit pcap_rtc_remove(struct platform_device *pdev) diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index f6ce63c443a0..1afa6d9fa9fb 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * An I2C driver for the PCF85063 RTC * Copyright 2014 Rose Technology @@ -5,16 +6,16 @@ * Author: Søren Andersen <san@rosetechnology.dk> * Maintainers: http://www.nslu2-linux.org/ * - * based on the other drivers in this same directory. - * - * 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. + * Copyright (C) 2019 Micro Crystal AG + * Author: Alexandre Belloni <alexandre.belloni@bootlin.com> */ #include <linux/i2c.h> #include <linux/bcd.h> #include <linux/rtc.h> #include <linux/module.h> +#include <linux/of_device.h> +#include <linux/pm_wakeirq.h> +#include <linux/regmap.h> /* * Information for this driver was pulled from the following datasheets. @@ -24,61 +25,47 @@ * * PCF85063A -- Rev. 6 — 18 November 2015 * PCF85063TP -- Rev. 4 — 6 May 2015 -*/ + * + * https://www.microcrystal.com/fileadmin/Media/Products/RTC/App.Manual/RV-8263-C7_App-Manual.pdf + * RV8263 -- Rev. 1.0 — January 2019 + */ #define PCF85063_REG_CTRL1 0x00 /* status */ #define PCF85063_REG_CTRL1_CAP_SEL BIT(0) #define PCF85063_REG_CTRL1_STOP BIT(5) -#define PCF85063_REG_SC 0x04 /* datetime */ -#define PCF85063_REG_SC_OS 0x80 - -static struct i2c_driver pcf85063_driver; - -static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1) -{ - int rc; - u8 reg; +#define PCF85063_REG_CTRL2 0x01 +#define PCF85063_CTRL2_AF BIT(6) +#define PCF85063_CTRL2_AIE BIT(7) - rc = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1); - if (rc < 0) { - dev_err(&client->dev, "Failing to stop the clock\n"); - return -EIO; - } +#define PCF85063_REG_OFFSET 0x02 +#define PCF85063_OFFSET_SIGN_BIT 6 /* 2's complement sign bit */ +#define PCF85063_OFFSET_MODE BIT(7) +#define PCF85063_OFFSET_STEP0 4340 +#define PCF85063_OFFSET_STEP1 4069 - /* stop the clock */ - reg = rc | PCF85063_REG_CTRL1_STOP; +#define PCF85063_REG_RAM 0x03 - rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, reg); - if (rc < 0) { - dev_err(&client->dev, "Failing to stop the clock\n"); - return -EIO; - } - - *ctrl1 = reg; - - return 0; -} - -static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) -{ - int rc; +#define PCF85063_REG_SC 0x04 /* datetime */ +#define PCF85063_REG_SC_OS 0x80 - /* start the clock */ - ctrl1 &= ~PCF85063_REG_CTRL1_STOP; +#define PCF85063_REG_ALM_S 0x0b +#define PCF85063_AEN BIT(7) - rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); - if (rc < 0) { - dev_err(&client->dev, "Failing to start the clock\n"); - return -EIO; - } +struct pcf85063_config { + struct regmap_config regmap; + unsigned has_alarms:1; + unsigned force_cap_7000:1; +}; - return 0; -} +struct pcf85063 { + struct rtc_device *rtc; + struct regmap *regmap; +}; static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct i2c_client *client = to_i2c_client(dev); + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); int rc; u8 regs[7]; @@ -88,16 +75,14 @@ static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) * event, the access must be finished within one second. So, read all * time/date registers in one turn. */ - rc = i2c_smbus_read_i2c_block_data(client, PCF85063_REG_SC, - sizeof(regs), regs); - if (rc != sizeof(regs)) { - dev_err(&client->dev, "date/time register read error\n"); - return -EIO; - } + rc = regmap_bulk_read(pcf85063->regmap, PCF85063_REG_SC, regs, + sizeof(regs)); + if (rc) + return rc; /* if the clock has lost its power it makes no sense to use its time */ if (regs[0] & PCF85063_REG_SC_OS) { - dev_warn(&client->dev, "Power loss detected, invalid time\n"); + dev_warn(&pcf85063->rtc->dev, "Power loss detected, invalid time\n"); return -EINVAL; } @@ -115,20 +100,18 @@ static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct i2c_client *client = to_i2c_client(dev); + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); int rc; u8 regs[7]; - u8 ctrl1; - - if ((tm->tm_year < 100) || (tm->tm_year > 199)) - return -EINVAL; /* * to accurately set the time, reset the divider chain and keep it in * reset state until all time/date registers are written */ - rc = pcf85063_stop_clock(client, &ctrl1); - if (rc != 0) + rc = regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL1, + PCF85063_REG_CTRL1_STOP, + PCF85063_REG_CTRL1_STOP); + if (rc) return rc; /* hours, minutes and seconds */ @@ -150,101 +133,351 @@ static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm) regs[6] = bin2bcd(tm->tm_year - 100); /* write all registers at once */ - rc = i2c_smbus_write_i2c_block_data(client, PCF85063_REG_SC, - sizeof(regs), regs); - if (rc < 0) { - dev_err(&client->dev, "date/time register write error\n"); + rc = regmap_bulk_write(pcf85063->regmap, PCF85063_REG_SC, + regs, sizeof(regs)); + if (rc) return rc; - } /* * Write the control register as a separate action since the size of * the register space is different between the PCF85063TP and * PCF85063A devices. The rollover point can not be used. */ - rc = pcf85063_start_clock(client, ctrl1); - if (rc != 0) - return rc; + return regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL1, + PCF85063_REG_CTRL1_STOP, 0); +} + +static int pcf85063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + u8 buf[4]; + unsigned int val; + int ret; + + ret = regmap_bulk_read(pcf85063->regmap, PCF85063_REG_ALM_S, + buf, sizeof(buf)); + if (ret) + return ret; + + alrm->time.tm_sec = bcd2bin(buf[0]); + alrm->time.tm_min = bcd2bin(buf[1]); + alrm->time.tm_hour = bcd2bin(buf[2]); + alrm->time.tm_mday = bcd2bin(buf[3]); + + ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val); + if (ret) + return ret; + + alrm->enabled = !!(val & PCF85063_CTRL2_AIE); return 0; } +static int pcf85063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + u8 buf[5]; + int ret; + + buf[0] = bin2bcd(alrm->time.tm_sec); + buf[1] = bin2bcd(alrm->time.tm_min); + buf[2] = bin2bcd(alrm->time.tm_hour); + buf[3] = bin2bcd(alrm->time.tm_mday); + buf[4] = PCF85063_AEN; /* Do not match on week day */ + + ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL2, + PCF85063_CTRL2_AIE | PCF85063_CTRL2_AF, 0); + if (ret) + return ret; + + ret = regmap_bulk_write(pcf85063->regmap, PCF85063_REG_ALM_S, + buf, sizeof(buf)); + if (ret) + return ret; + + return regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL2, + PCF85063_CTRL2_AIE | PCF85063_CTRL2_AF, + alrm->enabled ? PCF85063_CTRL2_AIE | PCF85063_CTRL2_AF : PCF85063_CTRL2_AF); +} + +static int pcf85063_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + + return regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL2, + PCF85063_CTRL2_AIE, + enabled ? PCF85063_CTRL2_AIE : 0); +} + +static irqreturn_t pcf85063_rtc_handle_irq(int irq, void *dev_id) +{ + struct pcf85063 *pcf85063 = dev_id; + unsigned int val; + int err; + + err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &val); + if (err) + return IRQ_NONE; + + if (val & PCF85063_CTRL2_AF) { + rtc_update_irq(pcf85063->rtc, 1, RTC_IRQF | RTC_AF); + regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL2, + PCF85063_CTRL2_AIE | PCF85063_CTRL2_AF, + 0); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static int pcf85063_read_offset(struct device *dev, long *offset) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + long val; + u32 reg; + int ret; + + ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, ®); + if (ret < 0) + return ret; + + val = sign_extend32(reg & ~PCF85063_OFFSET_MODE, + PCF85063_OFFSET_SIGN_BIT); + + if (reg & PCF85063_OFFSET_MODE) + *offset = val * PCF85063_OFFSET_STEP1; + else + *offset = val * PCF85063_OFFSET_STEP0; + + return 0; +} + +static int pcf85063_set_offset(struct device *dev, long offset) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + s8 mode0, mode1, reg; + unsigned int error0, error1; + + if (offset > PCF85063_OFFSET_STEP0 * 63) + return -ERANGE; + if (offset < PCF85063_OFFSET_STEP0 * -64) + return -ERANGE; + + mode0 = DIV_ROUND_CLOSEST(offset, PCF85063_OFFSET_STEP0); + mode1 = DIV_ROUND_CLOSEST(offset, PCF85063_OFFSET_STEP1); + + error0 = abs(offset - (mode0 * PCF85063_OFFSET_STEP0)); + error1 = abs(offset - (mode1 * PCF85063_OFFSET_STEP1)); + if (mode1 > 63 || mode1 < -64 || error0 < error1) + reg = mode0 & ~PCF85063_OFFSET_MODE; + else + reg = mode1 | PCF85063_OFFSET_MODE; + + return regmap_write(pcf85063->regmap, PCF85063_REG_OFFSET, reg); +} + +static int pcf85063_ioctl(struct device *dev, unsigned int cmd, + unsigned long arg) +{ + struct pcf85063 *pcf85063 = dev_get_drvdata(dev); + int status, ret = 0; + + switch (cmd) { + case RTC_VL_READ: + ret = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &status); + if (ret < 0) + return ret; + + if (status & PCF85063_REG_SC_OS) + dev_warn(&pcf85063->rtc->dev, "Voltage low, data loss detected.\n"); + + status &= PCF85063_REG_SC_OS; + + if (copy_to_user((void __user *)arg, &status, sizeof(int))) + return -EFAULT; + + return 0; + + case RTC_VL_CLR: + ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_SC, + PCF85063_REG_SC_OS, 0); + + return ret; + + default: + return -ENOIOCTLCMD; + } +} + static const struct rtc_class_ops pcf85063_rtc_ops = { .read_time = pcf85063_rtc_read_time, - .set_time = pcf85063_rtc_set_time + .set_time = pcf85063_rtc_set_time, + .read_offset = pcf85063_read_offset, + .set_offset = pcf85063_set_offset, + .ioctl = pcf85063_ioctl, +}; + +static const struct rtc_class_ops pcf85063_rtc_ops_alarm = { + .read_time = pcf85063_rtc_read_time, + .set_time = pcf85063_rtc_set_time, + .read_offset = pcf85063_read_offset, + .set_offset = pcf85063_set_offset, + .read_alarm = pcf85063_rtc_read_alarm, + .set_alarm = pcf85063_rtc_set_alarm, + .alarm_irq_enable = pcf85063_rtc_alarm_irq_enable, + .ioctl = pcf85063_ioctl, }; -static int pcf85063_load_capacitance(struct i2c_client *client) +static int pcf85063_nvmem_read(void *priv, unsigned int offset, + void *val, size_t bytes) { - u32 load; - int rc; - u8 reg; + return regmap_read(priv, PCF85063_REG_RAM, val); +} - rc = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1); - if (rc < 0) - return rc; +static int pcf85063_nvmem_write(void *priv, unsigned int offset, + void *val, size_t bytes) +{ + return regmap_write(priv, PCF85063_REG_RAM, *(u8 *)val); +} - reg = rc; - load = 7000; - of_property_read_u32(client->dev.of_node, "quartz-load-femtofarads", - &load); +static int pcf85063_load_capacitance(struct pcf85063 *pcf85063, + const struct device_node *np, + unsigned int force_cap) +{ + u32 load = 7000; + u8 reg = 0; + + if (force_cap) + load = force_cap; + else + of_property_read_u32(np, "quartz-load-femtofarads", &load); switch (load) { default: - dev_warn(&client->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 7000", + dev_warn(&pcf85063->rtc->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 7000", load); /* fall through */ case 7000: - reg &= ~PCF85063_REG_CTRL1_CAP_SEL; break; case 12500: - reg |= PCF85063_REG_CTRL1_CAP_SEL; + reg = PCF85063_REG_CTRL1_CAP_SEL; break; } - rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, reg); - - return rc; + return regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL1, + PCF85063_REG_CTRL1_CAP_SEL, reg); } -static int pcf85063_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static const struct pcf85063_config pcf85063a_config = { + .regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x11, + }, + .has_alarms = 1, +}; + +static const struct pcf85063_config pcf85063tp_config = { + .regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x0a, + }, +}; + +static const struct pcf85063_config rv8263_config = { + .regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x11, + }, + .has_alarms = 1, + .force_cap_7000 = 1, +}; + +static int pcf85063_probe(struct i2c_client *client) { - struct rtc_device *rtc; + struct pcf85063 *pcf85063; + unsigned int tmp; int err; + const struct pcf85063_config *config = &pcf85063tp_config; + const void *data = of_device_get_match_data(&client->dev); + struct nvmem_config nvmem_cfg = { + .name = "pcf85063_nvram", + .reg_read = pcf85063_nvmem_read, + .reg_write = pcf85063_nvmem_write, + .type = NVMEM_TYPE_BATTERY_BACKED, + .size = 1, + }; dev_dbg(&client->dev, "%s\n", __func__); - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -ENODEV; + pcf85063 = devm_kzalloc(&client->dev, sizeof(struct pcf85063), + GFP_KERNEL); + if (!pcf85063) + return -ENOMEM; + + if (data) + config = data; + + pcf85063->regmap = devm_regmap_init_i2c(client, &config->regmap); + if (IS_ERR(pcf85063->regmap)) + return PTR_ERR(pcf85063->regmap); - err = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1); - if (err < 0) { + i2c_set_clientdata(client, pcf85063); + + err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL1, &tmp); + if (err) { dev_err(&client->dev, "RTC chip is not present\n"); return err; } - err = pcf85063_load_capacitance(client); + pcf85063->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(pcf85063->rtc)) + return PTR_ERR(pcf85063->rtc); + + err = pcf85063_load_capacitance(pcf85063, client->dev.of_node, + config->force_cap_7000 ? 7000 : 0); if (err < 0) dev_warn(&client->dev, "failed to set xtal load capacitance: %d", err); - rtc = devm_rtc_device_register(&client->dev, - pcf85063_driver.driver.name, - &pcf85063_rtc_ops, THIS_MODULE); + pcf85063->rtc->ops = &pcf85063_rtc_ops; + pcf85063->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + pcf85063->rtc->range_max = RTC_TIMESTAMP_END_2099; + pcf85063->rtc->uie_unsupported = 1; + + if (config->has_alarms && client->irq > 0) { + err = devm_request_threaded_irq(&client->dev, client->irq, + NULL, pcf85063_rtc_handle_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "pcf85063", pcf85063); + if (err) { + dev_warn(&pcf85063->rtc->dev, + "unable to request IRQ, alarms disabled\n"); + } else { + pcf85063->rtc->ops = &pcf85063_rtc_ops_alarm; + device_init_wakeup(&client->dev, true); + err = dev_pm_set_wake_irq(&client->dev, client->irq); + if (err) + dev_err(&pcf85063->rtc->dev, + "failed to enable irq wake\n"); + } + } + + nvmem_cfg.priv = pcf85063->regmap; + rtc_nvmem_register(pcf85063->rtc, &nvmem_cfg); - return PTR_ERR_OR_ZERO(rtc); + return rtc_register_device(pcf85063->rtc); } -static const struct i2c_device_id pcf85063_id[] = { - { "pcf85063", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, pcf85063_id); - #ifdef CONFIG_OF static const struct of_device_id pcf85063_of_match[] = { - { .compatible = "nxp,pcf85063" }, + { .compatible = "nxp,pcf85063", .data = &pcf85063tp_config }, + { .compatible = "nxp,pcf85063tp", .data = &pcf85063tp_config }, + { .compatible = "nxp,pcf85063a", .data = &pcf85063a_config }, + { .compatible = "microcrystal,rv8263", .data = &rv8263_config }, {} }; MODULE_DEVICE_TABLE(of, pcf85063_of_match); @@ -255,8 +488,7 @@ static struct i2c_driver pcf85063_driver = { .name = "rtc-pcf85063", .of_match_table = of_match_ptr(pcf85063_of_match), }, - .probe = pcf85063_probe, - .id_table = pcf85063_id, + .probe_new = pcf85063_probe, }; module_i2c_driver(pcf85063_driver); diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index a3988079f60a..a075e77617dc 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -1,15 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * drivers/rtc/rtc-pcf85363.c * * Driver for NXP PCF85363 real-time clock. * * Copyright (C) 2017 Eric Nelson - * - * 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. - * - * Based loosely on rtc-8583 by Russell King, Wolfram Sang and Juergen Beisert */ #include <linux/module.h> #include <linux/i2c.h> @@ -112,10 +107,7 @@ #define NVRAM_SIZE 0x40 -static struct i2c_driver pcf85363_driver; - struct pcf85363 { - struct device *dev; struct rtc_device *rtc; struct regmap *regmap; }; @@ -386,9 +378,6 @@ static int pcf85363_probe(struct i2c_client *client, if (data) config = data; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - return -ENODEV; - pcf85363 = devm_kzalloc(&client->dev, sizeof(struct pcf85363), GFP_KERNEL); if (!pcf85363) @@ -400,20 +389,21 @@ static int pcf85363_probe(struct i2c_client *client, return PTR_ERR(pcf85363->regmap); } - pcf85363->dev = &client->dev; i2c_set_clientdata(client, pcf85363); - pcf85363->rtc = devm_rtc_allocate_device(pcf85363->dev); + pcf85363->rtc = devm_rtc_allocate_device(&client->dev); if (IS_ERR(pcf85363->rtc)) return PTR_ERR(pcf85363->rtc); pcf85363->rtc->ops = &rtc_ops; + pcf85363->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + pcf85363->rtc->range_max = RTC_TIMESTAMP_END_2099; if (client->irq > 0) { regmap_write(pcf85363->regmap, CTRL_FLAGS, 0); regmap_update_bits(pcf85363->regmap, CTRL_PIN_IO, PIN_IO_INTA_OUT, PIN_IO_INTAPM); - ret = devm_request_threaded_irq(pcf85363->dev, client->irq, + ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf85363_rtc_handle_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "pcf85363", client); diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c index 347288bff438..f0336d691e6c 100644 --- a/drivers/rtc/rtc-ps3.c +++ b/drivers/rtc/rtc-ps3.c @@ -1,20 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * PS3 RTC Driver * * Copyright 2009 Sony Corporation - * - * 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; version 2 of the License. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. - * If not, see <http://www.gnu.org/licenses/>. */ #include <linux/kernel.h> @@ -40,16 +28,13 @@ static u64 read_rtc(void) static int ps3_get_time(struct device *dev, struct rtc_time *tm) { - rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm); + rtc_time64_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm); return 0; } static int ps3_set_time(struct device *dev, struct rtc_time *tm) { - unsigned long now; - - rtc_tm_to_time(tm, &now); - ps3_os_area_set_rtc_diff(now - read_rtc()); + ps3_os_area_set_rtc_diff(rtc_tm_to_time64(tm) - read_rtc()); return 0; } @@ -62,13 +47,16 @@ static int __init ps3_rtc_probe(struct platform_device *dev) { struct rtc_device *rtc; - rtc = devm_rtc_device_register(&dev->dev, "rtc-ps3", &ps3_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_allocate_device(&dev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + rtc->ops = &ps3_rtc_ops; + rtc->range_max = U64_MAX; + platform_set_drvdata(dev, rtc); - return 0; + + return rtc_register_device(rtc); } static struct platform_driver ps3_rtc_driver = { diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index e1887b86fdc7..d4766734e40b 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c @@ -145,8 +145,7 @@ static void rtsr_set_bits(struct pxa_rtc *pxa_rtc, u32 mask) static irqreturn_t pxa_rtc_irq(int irq, void *dev_id) { - struct platform_device *pdev = to_platform_device(dev_id); - struct pxa_rtc *pxa_rtc = platform_get_drvdata(pdev); + struct pxa_rtc *pxa_rtc = dev_get_drvdata(dev_id); u32 rtsr; unsigned long events = 0; diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index 1fb864d4ef83..5c5d9f125669 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c @@ -336,8 +336,7 @@ static const struct rtc_class_ops rk808_rtc_ops = { /* Turn off the alarm if it should not be a wake source. */ static int rk808_rtc_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); if (device_may_wakeup(dev)) enable_irq_wake(rk808_rtc->irq); @@ -350,8 +349,7 @@ static int rk808_rtc_suspend(struct device *dev) */ static int rk808_rtc_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct rk808_rtc *rk808_rtc = dev_get_drvdata(&pdev->dev); + struct rk808_rtc *rk808_rtc = dev_get_drvdata(dev); if (device_may_wakeup(dev)) disable_irq_wake(rk808_rtc->irq); diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c index 5899ca368d59..71e20a6bd387 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -21,6 +21,8 @@ #include <linux/of_gpio.h> #include <linux/regmap.h> #include <linux/rtc.h> +#include <linux/of.h> +#include <linux/of_device.h> #include <linux/spi/spi.h> /* RX-6110 Register definitions */ @@ -379,9 +381,16 @@ static const struct spi_device_id rx6110_id[] = { }; MODULE_DEVICE_TABLE(spi, rx6110_id); +static const struct of_device_id rx6110_spi_of_match[] = { + { .compatible = "epson,rx6110" }, + { }, +}; +MODULE_DEVICE_TABLE(of, rx6110_spi_of_match); + static struct spi_driver rx6110_driver = { .driver = { .name = RX6110_DRIVER_NAME, + .of_match_table = of_match_ptr(rx6110_spi_of_match), }, .probe = rx6110_probe, .remove = rx6110_remove, diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 41de38acc570..fddc996cb38d 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -311,7 +311,7 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 + (ald[1] & 0x20 ? 12 : 0); - dev_dbg(dev, "%s: date: %ptRr\n", __func__, t); + dev_dbg(dev, "%s: date: %ptRr\n", __func__, &t->time); t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE); t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 1d3de2a3d1a4..579b3ff5c644 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -276,6 +276,9 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) struct sh_rtc *rtc = dev_get_drvdata(dev); unsigned int sec128, sec2, yr, yr100, cf_bit; + if (!(readb(rtc->regbase + RCR2) & RCR2_RTCEN)) + return -EINVAL; + do { unsigned int tmp; @@ -466,7 +469,6 @@ static int __init sh_rtc_probe(struct platform_device *pdev) { struct sh_rtc *rtc; struct resource *res; - struct rtc_time r; char clk_name[6]; int clk_id, ret; @@ -528,6 +530,10 @@ static int __init sh_rtc_probe(struct platform_device *pdev) rtc->clk = NULL; } + rtc->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc->rtc_dev)) + return PTR_ERR(rtc->rtc_dev); + clk_enable(rtc->clk); rtc->capabilities = RTC_DEF_CAPABILITIES; @@ -591,21 +597,21 @@ static int __init sh_rtc_probe(struct platform_device *pdev) sh_rtc_setaie(&pdev->dev, 0); sh_rtc_setcie(&pdev->dev, 0); - rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, "sh", - &sh_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc->rtc_dev)) { - ret = PTR_ERR(rtc->rtc_dev); - goto err_unmap; - } - + rtc->rtc_dev->ops = &sh_rtc_ops; rtc->rtc_dev->max_user_freq = 256; - /* reset rtc to epoch 0 if time is invalid */ - if (rtc_read_time(rtc->rtc_dev, &r) < 0) { - rtc_time_to_tm(0, &r); - rtc_set_time(rtc->rtc_dev, &r); + if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { + rtc->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_1900; + rtc->rtc_dev->range_max = RTC_TIMESTAMP_END_9999; + } else { + rtc->rtc_dev->range_min = mktime64(1999, 1, 1, 0, 0, 0); + rtc->rtc_dev->range_max = mktime64(2098, 12, 31, 23, 59, 59); } + ret = rtc_register_device(rtc->rtc_dev); + if (ret) + goto err_unmap; + device_init_wakeup(&pdev->dev, 1); return 0; diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 2a9e151cae99..9ba28d1ebd87 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -279,7 +279,7 @@ static const struct of_device_id sirfsoc_rtc_of_match[] = { {}, }; -const struct regmap_config sysrtc_regmap_config = { +static const struct regmap_config sysrtc_regmap_config = { .reg_bits = 32, .val_bits = 32, .fast_io = true, diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 0b9eff19149b..7ee673a25fd0 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -9,6 +9,7 @@ #include <linux/of.h> #include <linux/of_device.h> #include <linux/platform_device.h> +#include <linux/pm_wakeirq.h> #include <linux/rtc.h> #include <linux/clk.h> #include <linux/mfd/syscon.h> @@ -271,7 +272,6 @@ static const struct regmap_config snvs_rtc_config = { static int snvs_rtc_probe(struct platform_device *pdev) { struct snvs_rtc_data *data; - struct resource *res; int ret; void __iomem *mmio; @@ -283,9 +283,8 @@ static int snvs_rtc_probe(struct platform_device *pdev) if (IS_ERR(data->regmap)) { dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n"); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - mmio = devm_ioremap_resource(&pdev->dev, res); + mmio = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(mmio)) return PTR_ERR(mmio); @@ -332,6 +331,9 @@ static int snvs_rtc_probe(struct platform_device *pdev) } device_init_wakeup(&pdev->dev, true); + ret = dev_pm_set_wake_irq(&pdev->dev, data->irq); + if (ret) + dev_err(&pdev->dev, "failed to enable irq wake\n"); ret = devm_request_irq(&pdev->dev, data->irq, snvs_rtc_irq_handler, IRQF_SHARED, "rtc alarm", &pdev->dev); @@ -358,18 +360,7 @@ error_rtc_device_register: return ret; } -#ifdef CONFIG_PM_SLEEP -static int snvs_rtc_suspend(struct device *dev) -{ - struct snvs_rtc_data *data = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - return enable_irq_wake(data->irq); - - return 0; -} - -static int snvs_rtc_suspend_noirq(struct device *dev) +static int __maybe_unused snvs_rtc_suspend_noirq(struct device *dev) { struct snvs_rtc_data *data = dev_get_drvdata(dev); @@ -379,17 +370,7 @@ static int snvs_rtc_suspend_noirq(struct device *dev) return 0; } -static int snvs_rtc_resume(struct device *dev) -{ - struct snvs_rtc_data *data = dev_get_drvdata(dev); - - if (device_may_wakeup(dev)) - return disable_irq_wake(data->irq); - - return 0; -} - -static int snvs_rtc_resume_noirq(struct device *dev) +static int __maybe_unused snvs_rtc_resume_noirq(struct device *dev) { struct snvs_rtc_data *data = dev_get_drvdata(dev); @@ -400,20 +381,9 @@ static int snvs_rtc_resume_noirq(struct device *dev) } static const struct dev_pm_ops snvs_rtc_pm_ops = { - .suspend = snvs_rtc_suspend, - .suspend_noirq = snvs_rtc_suspend_noirq, - .resume = snvs_rtc_resume, - .resume_noirq = snvs_rtc_resume_noirq, + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(snvs_rtc_suspend_noirq, snvs_rtc_resume_noirq) }; -#define SNVS_RTC_PM_OPS (&snvs_rtc_pm_ops) - -#else - -#define SNVS_RTC_PM_OPS NULL - -#endif - static const struct of_device_id snvs_dt_ids[] = { { .compatible = "fsl,sec-v4.0-mon-rtc-lp", }, { /* sentinel */ } @@ -423,7 +393,7 @@ MODULE_DEVICE_TABLE(of, snvs_dt_ids); static struct platform_driver snvs_rtc_driver = { .driver = { .name = "snvs_rtc", - .pm = SNVS_RTC_PM_OPS, + .pm = &snvs_rtc_pm_ops, .of_match_table = snvs_dt_ids, }, .probe = snvs_rtc_probe, diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index c5908cfea234..8e6c9b3bcc29 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -788,11 +788,14 @@ static int stm32_rtc_probe(struct platform_device *pdev) ret = device_init_wakeup(&pdev->dev, true); if (rtc->data->has_wakeirq) { rtc->wakeirq_alarm = platform_get_irq(pdev, 1); - if (rtc->wakeirq_alarm <= 0) - ret = rtc->wakeirq_alarm; - else + if (rtc->wakeirq_alarm > 0) { ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, rtc->wakeirq_alarm); + } else { + ret = rtc->wakeirq_alarm; + if (rtc->wakeirq_alarm == -EPROBE_DEFER) + goto err; + } } if (ret) dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret); diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index b76318fd5bb0..ff6488be385f 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Freescale STMP37XX/STMP378X Real Time Clock driver * @@ -8,15 +9,6 @@ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved. * Copyright 2011 Wolfram Sang, Pengutronix e.K. */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/io.h> @@ -160,15 +152,15 @@ static int stmp3xxx_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) if (ret) return ret; - rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); + rtc_time64_to_tm(readl(rtc_data->io + STMP3XXX_RTC_SECONDS), rtc_tm); return 0; } -static int stmp3xxx_rtc_set_mmss(struct device *dev, unsigned long t) +static int stmp3xxx_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) { struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - writel(t, rtc_data->io + STMP3XXX_RTC_SECONDS); + writel(rtc_tm_to_time64(rtc_tm), rtc_data->io + STMP3XXX_RTC_SECONDS); return stmp3xxx_wait_time(rtc_data); } @@ -214,17 +206,15 @@ static int stmp3xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - rtc_time_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); + rtc_time64_to_tm(readl(rtc_data->io + STMP3XXX_RTC_ALARM), &alm->time); return 0; } static int stmp3xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { - unsigned long t; struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); - rtc_tm_to_time(&alm->time, &t); - writel(t, rtc_data->io + STMP3XXX_RTC_ALARM); + writel(rtc_tm_to_time64(&alm->time), rtc_data->io + STMP3XXX_RTC_ALARM); stmp3xxx_alarm_irq_enable(dev, alm->enabled); @@ -235,7 +225,7 @@ static const struct rtc_class_ops stmp3xxx_rtc_ops = { .alarm_irq_enable = stmp3xxx_alarm_irq_enable, .read_time = stmp3xxx_rtc_gettime, - .set_mmss = stmp3xxx_rtc_set_mmss, + .set_time = stmp3xxx_rtc_settime, .read_alarm = stmp3xxx_rtc_read_alarm, .set_alarm = stmp3xxx_rtc_set_alarm, }; @@ -361,8 +351,7 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) STMP3XXX_RTC_CTRL_ALARM_IRQ_EN, rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); - rtc_data->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &stmp3xxx_rtc_ops, THIS_MODULE); + rtc_data->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc_data->rtc)) return PTR_ERR(rtc_data->rtc); @@ -374,6 +363,13 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) return err; } + rtc_data->rtc->ops = &stmp3xxx_rtc_ops; + rtc_data->rtc->range_max = U32_MAX; + + err = rtc_register_device(rtc_data->rtc); + if (err) + return err; + stmp3xxx_wdt_register(pdev); return 0; } diff --git a/drivers/rtc/rtc-sun4v.c b/drivers/rtc/rtc-sun4v.c index 11bc562eba5d..036463dfa103 100644 --- a/drivers/rtc/rtc-sun4v.c +++ b/drivers/rtc/rtc-sun4v.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* rtc-sun4v.c: Hypervisor based RTC for SUN4V systems. * * Author: David S. Miller - * License: GPL * * Copyright (C) 2008 David S. Miller <davem@davemloft.net> */ @@ -39,7 +39,7 @@ retry: static int sun4v_read_time(struct device *dev, struct rtc_time *tm) { - rtc_time_to_tm(hypervisor_get_time(), tm); + rtc_time64_to_tm(hypervisor_get_time(), tm); return 0; } @@ -66,14 +66,7 @@ retry: static int sun4v_set_time(struct device *dev, struct rtc_time *tm) { - unsigned long secs; - int err; - - err = rtc_tm_to_time(tm, &secs); - if (err) - return err; - - return hypervisor_set_time(secs); + return hypervisor_set_time(rtc_tm_to_time64(tm)); } static const struct rtc_class_ops sun4v_rtc_ops = { @@ -85,13 +78,15 @@ static int __init sun4v_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - rtc = devm_rtc_device_register(&pdev->dev, "sun4v", - &sun4v_rtc_ops, THIS_MODULE); + rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + rtc->ops = &sun4v_rtc_ops; + rtc->range_max = U64_MAX; platform_set_drvdata(pdev, rtc); - return 0; + + return rtc_register_device(rtc); } static struct platform_driver sun4v_rtc_driver = { diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index c6b0a99aa3a9..f0ce76865434 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * An RTC driver for the NVIDIA Tegra 200 series internal RTC. * * Copyright (c) 2010, NVIDIA Corporation. - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <linux/clk.h> @@ -123,7 +110,7 @@ static int tegra_rtc_read_time(struct device *dev, struct rtc_time *tm) spin_unlock_irqrestore(&info->tegra_rtc_lock, sl_irq_flags); - rtc_time_to_tm(sec, tm); + rtc_time64_to_tm(sec, tm); dev_vdbg(dev, "time read as %lu. %ptR\n", sec, tm); @@ -137,7 +124,7 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) int ret; /* convert tm to seconds. */ - rtc_tm_to_time(tm, &sec); + sec = rtc_tm_to_time64(tm); dev_vdbg(dev, "time set to %lu. %ptR\n", sec, tm); @@ -166,7 +153,7 @@ static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) } else { /* alarm is enabled. */ alarm->enabled = 1; - rtc_time_to_tm(sec, &alarm->time); + rtc_time64_to_tm(sec, &alarm->time); } tmp = readl(info->rtc_base + TEGRA_RTC_REG_INTR_STATUS); @@ -204,7 +191,7 @@ static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) unsigned long sec; if (alarm->enabled) - rtc_tm_to_time(&alarm->time, &sec); + sec = rtc_tm_to_time64(&alarm->time); else sec = 0; @@ -306,6 +293,13 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) info->tegra_rtc_irq = ret; + info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc_dev)) + return PTR_ERR(info->rtc_dev); + + info->rtc_dev->ops = &tegra_rtc_ops; + info->rtc_dev->range_max = U32_MAX; + info->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(info->clk)) return PTR_ERR(info->clk); @@ -327,16 +321,6 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - info->rtc_dev = devm_rtc_device_register(&pdev->dev, - dev_name(&pdev->dev), &tegra_rtc_ops, - THIS_MODULE); - if (IS_ERR(info->rtc_dev)) { - ret = PTR_ERR(info->rtc_dev); - dev_err(&pdev->dev, "Unable to register device (err=%d).\n", - ret); - goto disable_clk; - } - ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, tegra_rtc_irq_handler, IRQF_TRIGGER_HIGH, dev_name(&pdev->dev), &pdev->dev); @@ -347,6 +331,13 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) goto disable_clk; } + ret = rtc_register_device(info->rtc_dev); + if (ret) { + dev_err(&pdev->dev, "Unable to register device (err=%d).\n", + ret); + goto disable_clk; + } + dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); return 0; diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 6c5f09c815e8..b298e9902f45 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c @@ -70,11 +70,11 @@ static int test_rtc_read_time(struct device *dev, struct rtc_time *tm) return 0; } -static int test_rtc_set_mmss64(struct device *dev, time64_t secs) +static int test_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct rtc_test_data *rtd = dev_get_drvdata(dev); - rtd->offset = secs - ktime_get_real_seconds(); + rtd->offset = rtc_tm_to_time64(tm) - ktime_get_real_seconds(); return 0; } @@ -94,15 +94,15 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) static const struct rtc_class_ops test_rtc_ops_noalm = { .read_time = test_rtc_read_time, - .set_mmss64 = test_rtc_set_mmss64, + .set_time = test_rtc_set_time, .alarm_irq_enable = test_rtc_alarm_irq_enable, }; static const struct rtc_class_ops test_rtc_ops = { .read_time = test_rtc_read_time, + .set_time = test_rtc_set_time, .read_alarm = test_rtc_read_alarm, .set_alarm = test_rtc_set_alarm, - .set_mmss64 = test_rtc_set_mmss64, .alarm_irq_enable = test_rtc_alarm_irq_enable, }; @@ -152,7 +152,8 @@ static int __init test_init(void) { int i, err; - if ((err = platform_driver_register(&test_driver))) + err = platform_driver_register(&test_driver); + if (err) return err; err = -ENOMEM; diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 2d24babc4057..5a29915a06ec 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -42,11 +42,6 @@ struct tx4939rtc_plat_data { spinlock_t lock; }; -static struct tx4939rtc_plat_data *get_tx4939rtc_plat_data(struct device *dev) -{ - return platform_get_drvdata(to_platform_device(dev)); -} - static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) { int i = 0; @@ -64,7 +59,7 @@ static int tx4939_rtc_cmd(struct tx4939_rtc_reg __iomem *rtcreg, int cmd) static int tx4939_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; unsigned long secs = rtc_tm_to_time64(tm); int i, ret; @@ -89,7 +84,7 @@ static int tx4939_rtc_set_time(struct device *dev, struct rtc_time *tm) static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; int i, ret; unsigned long sec; @@ -115,7 +110,7 @@ static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; int i, ret; unsigned long sec; @@ -140,7 +135,7 @@ static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; int i, ret; unsigned long sec; @@ -170,7 +165,7 @@ static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev); spin_lock_irq(&pdata->lock); tx4939_rtc_cmd(pdata->rtcreg, @@ -182,7 +177,7 @@ static int tx4939_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) static irqreturn_t tx4939_rtc_interrupt(int irq, void *dev_id) { - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev_id); + struct tx4939rtc_plat_data *pdata = dev_get_drvdata(dev_id); struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; unsigned long events = RTC_IRQF; diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 7b824dabf104..d2e8b21c90c4 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Real Time Clock driver for Wolfson Microelectronics WM831x * @@ -5,11 +6,6 @@ * * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> * - * 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/module.h> @@ -155,7 +151,7 @@ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm) if (memcmp(time1, time2, sizeof(time1)) == 0) { u32 time = (time1[0] << 16) | time1[1]; - rtc_time_to_tm(time, tm); + rtc_time64_to_tm(time, tm); return 0; } @@ -169,15 +165,17 @@ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm) /* * Set current time and date in RTC */ -static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time) +static int wm831x_rtc_settime(struct device *dev, struct rtc_time *tm) { struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); struct wm831x *wm831x = wm831x_rtc->wm831x; struct rtc_time new_tm; - unsigned long new_time; + unsigned long time, new_time; int ret; int count = 0; + time = rtc_tm_to_time64(tm); + ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_1, (time >> 16) & 0xffff); if (ret < 0) { @@ -215,11 +213,7 @@ static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time) if (ret < 0) return ret; - ret = rtc_tm_to_time(&new_tm, &new_time); - if (ret < 0) { - dev_err(dev, "Failed to convert time: %d\n", ret); - return ret; - } + new_time = rtc_tm_to_time64(&new_tm); /* Allow a second of change in case of tick */ if (new_time - time > 1) { @@ -249,7 +243,7 @@ static int wm831x_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) time = (data[0] << 16) | data[1]; - rtc_time_to_tm(time, &alrm->time); + rtc_time64_to_tm(time, &alrm->time); ret = wm831x_reg_read(wm831x_rtc->wm831x, WM831X_RTC_CONTROL); if (ret < 0) { @@ -288,11 +282,7 @@ static int wm831x_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) int ret; unsigned long time; - ret = rtc_tm_to_time(&alrm->time, &time); - if (ret < 0) { - dev_err(dev, "Failed to convert time: %d\n", ret); - return ret; - } + time = rtc_tm_to_time64(&alrm->time); ret = wm831x_rtc_stop_alarm(wm831x_rtc); if (ret < 0) { @@ -346,7 +336,7 @@ static irqreturn_t wm831x_alm_irq(int irq, void *data) static const struct rtc_class_ops wm831x_rtc_ops = { .read_time = wm831x_rtc_readtime, - .set_mmss = wm831x_rtc_set_mmss, + .set_time = wm831x_rtc_settime, .read_alarm = wm831x_rtc_readalarm, .set_alarm = wm831x_rtc_setalarm, .alarm_irq_enable = wm831x_rtc_alarm_irq_enable, @@ -356,11 +346,10 @@ static const struct rtc_class_ops wm831x_rtc_ops = { /* Turn off the alarm if it should not be a wake source. */ static int wm831x_rtc_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev); + struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); int ret, enable; - if (wm831x_rtc->alarm_enabled && device_may_wakeup(&pdev->dev)) + if (wm831x_rtc->alarm_enabled && device_may_wakeup(dev)) enable = WM831X_RTC_ALM_ENA; else enable = 0; @@ -368,7 +357,7 @@ static int wm831x_rtc_suspend(struct device *dev) ret = wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL, WM831X_RTC_ALM_ENA, enable); if (ret != 0) - dev_err(&pdev->dev, "Failed to update RTC alarm: %d\n", ret); + dev_err(dev, "Failed to update RTC alarm: %d\n", ret); return 0; } @@ -378,15 +367,13 @@ static int wm831x_rtc_suspend(struct device *dev) */ static int wm831x_rtc_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev); + struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); int ret; if (wm831x_rtc->alarm_enabled) { ret = wm831x_rtc_start_alarm(wm831x_rtc); if (ret != 0) - dev_err(&pdev->dev, - "Failed to restart RTC alarm: %d\n", ret); + dev_err(dev, "Failed to restart RTC alarm: %d\n", ret); } return 0; @@ -395,14 +382,13 @@ static int wm831x_rtc_resume(struct device *dev) /* Unconditionally disable the alarm */ static int wm831x_rtc_freeze(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(&pdev->dev); + struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev); int ret; ret = wm831x_set_bits(wm831x_rtc->wm831x, WM831X_RTC_CONTROL, WM831X_RTC_ALM_ENA, 0); if (ret != 0) - dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", ret); + dev_err(dev, "Failed to stop RTC alarm: %d\n", ret); return 0; } @@ -429,19 +415,23 @@ static int wm831x_rtc_probe(struct platform_device *pdev) ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL); if (ret < 0) { dev_err(&pdev->dev, "Failed to read RTC control: %d\n", ret); - goto err; + return ret; } if (ret & WM831X_RTC_ALM_ENA) wm831x_rtc->alarm_enabled = 1; device_init_wakeup(&pdev->dev, 1); - wm831x_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm831x", - &wm831x_rtc_ops, THIS_MODULE); - if (IS_ERR(wm831x_rtc->rtc)) { - ret = PTR_ERR(wm831x_rtc->rtc); - goto err; - } + wm831x_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(wm831x_rtc->rtc)) + return PTR_ERR(wm831x_rtc->rtc); + + wm831x_rtc->rtc->ops = &wm831x_rtc_ops; + wm831x_rtc->rtc->range_max = U32_MAX; + + ret = rtc_register_device(wm831x_rtc->rtc); + if (ret) + return ret; ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL, wm831x_alm_irq, @@ -455,9 +445,6 @@ static int wm831x_rtc_probe(struct platform_device *pdev) wm831x_rtc_add_randomness(wm831x); return 0; - -err: - return ret; } static const struct dev_pm_ops wm831x_rtc_pm_ops = { diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c index 483c7993516b..f54fa12c4b4b 100644 --- a/drivers/rtc/rtc-wm8350.c +++ b/drivers/rtc/rtc-wm8350.c @@ -340,8 +340,7 @@ static const struct rtc_class_ops wm8350_rtc_ops = { #ifdef CONFIG_PM_SLEEP static int wm8350_rtc_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); + struct wm8350 *wm8350 = dev_get_drvdata(dev); int ret = 0; u16 reg; @@ -351,8 +350,7 @@ static int wm8350_rtc_suspend(struct device *dev) reg & WM8350_RTC_ALMSTS) { ret = wm8350_rtc_stop_alarm(wm8350); if (ret != 0) - dev_err(&pdev->dev, "Failed to stop RTC alarm: %d\n", - ret); + dev_err(dev, "Failed to stop RTC alarm: %d\n", ret); } return ret; @@ -360,15 +358,13 @@ static int wm8350_rtc_suspend(struct device *dev) static int wm8350_rtc_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); + struct wm8350 *wm8350 = dev_get_drvdata(dev); int ret; if (wm8350->rtc.alarm_enabled) { ret = wm8350_rtc_start_alarm(wm8350); if (ret != 0) - dev_err(&pdev->dev, - "Failed to restart RTC alarm: %d\n", ret); + dev_err(dev, "Failed to restart RTC alarm: %d\n", ret); } return 0; diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c index f08f18e4fcdf..ad2ae2f0536e 100644 --- a/drivers/rtc/rtc-x1205.c +++ b/drivers/rtc/rtc-x1205.c @@ -673,9 +673,16 @@ static const struct i2c_device_id x1205_id[] = { }; MODULE_DEVICE_TABLE(i2c, x1205_id); +static const struct of_device_id x1205_dt_ids[] = { + { .compatible = "xircom,x1205", }, + {}, +}; +MODULE_DEVICE_TABLE(of, x1205_dt_ids); + static struct i2c_driver x1205_driver = { .driver = { .name = "rtc-x1205", + .of_match_table = x1205_dt_ids, }, .probe = x1205_probe, .remove = x1205_remove, diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index 153820876a82..9888383f0088 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c @@ -1,34 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * APM X-Gene SoC Real Time Clock Driver * * Copyright (c) 2014, Applied Micro Circuits Corporation * Author: Rameshwar Prasad Sahu <rsahu@apm.com> * Loc Ho <lho@apm.com> - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * */ +#include <linux/clk.h> +#include <linux/delay.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/clk.h> -#include <linux/delay.h> #include <linux/rtc.h> +#include <linux/slab.h> /* RTC CSR Registers */ #define RTC_CCVR 0x00 @@ -48,7 +35,6 @@ struct xgene_rtc_dev { struct rtc_device *rtc; struct device *dev; - unsigned long alarm_time; void __iomem *csr_base; struct clk *clk; unsigned int irq_wake; @@ -59,11 +45,11 @@ static int xgene_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); - rtc_time_to_tm(readl(pdata->csr_base + RTC_CCVR), tm); + rtc_time64_to_tm(readl(pdata->csr_base + RTC_CCVR), tm); return 0; } -static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs) +static int xgene_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); @@ -71,7 +57,7 @@ static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs) * NOTE: After the following write, the RTC_CCVR is only reflected * after the update cycle of 1 seconds. */ - writel((u32) secs, pdata->csr_base + RTC_CLR); + writel((u32)rtc_tm_to_time64(tm), pdata->csr_base + RTC_CLR); readl(pdata->csr_base + RTC_CLR); /* Force a barrier */ return 0; @@ -81,7 +67,8 @@ static int xgene_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); - rtc_time_to_tm(pdata->alarm_time, &alrm->time); + /* If possible, CMR should be read here */ + rtc_time64_to_tm(0, &alrm->time); alrm->enabled = readl(pdata->csr_base + RTC_CCR) & RTC_CCR_IE; return 0; @@ -115,11 +102,8 @@ static int xgene_rtc_alarm_irq_enabled(struct device *dev) static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct xgene_rtc_dev *pdata = dev_get_drvdata(dev); - unsigned long alarm_time; - rtc_tm_to_time(&alrm->time, &alarm_time); - pdata->alarm_time = alarm_time; - writel((u32) pdata->alarm_time, pdata->csr_base + RTC_CMR); + writel((u32)rtc_tm_to_time64(&alrm->time), pdata->csr_base + RTC_CMR); xgene_rtc_alarm_irq_enable(dev, alrm->enabled); @@ -128,7 +112,7 @@ static int xgene_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) static const struct rtc_class_ops xgene_rtc_ops = { .read_time = xgene_rtc_read_time, - .set_mmss = xgene_rtc_set_mmss, + .set_time = xgene_rtc_set_time, .read_alarm = xgene_rtc_read_alarm, .set_alarm = xgene_rtc_set_alarm, .alarm_irq_enable = xgene_rtc_alarm_irq_enable, @@ -136,7 +120,7 @@ static const struct rtc_class_ops xgene_rtc_ops = { static irqreturn_t xgene_rtc_interrupt(int irq, void *id) { - struct xgene_rtc_dev *pdata = (struct xgene_rtc_dev *) id; + struct xgene_rtc_dev *pdata = id; /* Check if interrupt asserted */ if (!(readl(pdata->csr_base + RTC_STAT) & RTC_STAT_BIT)) @@ -168,6 +152,10 @@ static int xgene_rtc_probe(struct platform_device *pdev) if (IS_ERR(pdata->csr_base)) return PTR_ERR(pdata->csr_base); + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(pdata->rtc)) + return PTR_ERR(pdata->rtc); + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "No IRQ resource\n"); @@ -198,15 +186,16 @@ static int xgene_rtc_probe(struct platform_device *pdev) return ret; } - pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &xgene_rtc_ops, THIS_MODULE); - if (IS_ERR(pdata->rtc)) { - clk_disable_unprepare(pdata->clk); - return PTR_ERR(pdata->rtc); - } - /* HW does not support update faster than 1 seconds */ pdata->rtc->uie_unsupported = 1; + pdata->rtc->ops = &xgene_rtc_ops; + pdata->rtc->range_max = U32_MAX; + + ret = rtc_register_device(pdata->rtc); + if (ret) { + clk_disable_unprepare(pdata->clk); + return ret; + } return 0; } diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index bb950945ec7f..00639594de0c 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -1,20 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Xilinx Zynq Ultrascale+ MPSoC Real Time Clock Driver * * Copyright (C) 2015 Xilinx, Inc. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. - * */ #include <linux/delay.h> diff --git a/drivers/rtc/sysfs.c b/drivers/rtc/sysfs.c index a8f22ee726bb..be3531e7f868 100644 --- a/drivers/rtc/sysfs.c +++ b/drivers/rtc/sysfs.c @@ -1,20 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 /* * RTC subsystem, sysfs interface * * Copyright (C) 2005 Tower Technologies * Author: Alessandro Zummo <a.zummo@towertech.it> - * - * 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. -*/ + */ #include <linux/module.h> #include <linux/rtc.h> #include "rtc-core.h" - /* device attributes */ /* @@ -86,7 +82,7 @@ max_user_freq_show(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t max_user_freq_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t n) + const char *buf, size_t n) { struct rtc_device *rtc = to_rtc_device(dev); unsigned long val; @@ -116,12 +112,11 @@ hctosys_show(struct device *dev, struct device_attribute *attr, char *buf) { #ifdef CONFIG_RTC_HCTOSYS_DEVICE if (rtc_hctosys_ret == 0 && - strcmp(dev_name(&to_rtc_device(dev)->dev), - CONFIG_RTC_HCTOSYS_DEVICE) == 0) + strcmp(dev_name(&to_rtc_device(dev)->dev), + CONFIG_RTC_HCTOSYS_DEVICE) == 0) return sprintf(buf, "1\n"); - else #endif - return sprintf(buf, "0\n"); + return sprintf(buf, "0\n"); } static DEVICE_ATTR_RO(hctosys); @@ -175,15 +170,15 @@ wakealarm_store(struct device *dev, struct device_attribute *attr, if (*buf_ptr == '=') { buf_ptr++; push = 1; - } else + } else { adjust = 1; + } } retval = kstrtos64(buf_ptr, 0, &alarm); if (retval) return retval; - if (adjust) { + if (adjust) alarm += now; - } if (alarm > now || push) { /* Avoid accidentally clobbering active alarms; we can't * entirely prevent that here, without even the minimal diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index 718293d72426..8b70f0520e13 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -1,9 +1,4 @@ -/* - * 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. - * - */ +// SPDX-License-Identifier: GPL-2.0 #include <linux/rtc.h> #include <linux/time.h> @@ -35,8 +30,7 @@ int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec) if (!rtc) goto out_err; - if (!rtc->ops || (!rtc->ops->set_time && !rtc->ops->set_mmss64 && - !rtc->ops->set_mmss)) + if (!rtc->ops || !rtc->ops->set_time) goto out_close; /* Compute the value of tv_nsec we require the caller to supply in @@ -58,9 +52,6 @@ int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec) rtc_time64_to_tm(to_set.tv_sec, &tm); - /* rtc_hctosys exclusively uses UTC, so we call set_time here, not - * set_mmss. - */ err = rtc_set_time(rtc, &tm); out_close: diff --git a/include/linux/rtc.h b/include/linux/rtc.h index f89bfbb54902..df666cf29ef1 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -79,8 +79,6 @@ struct rtc_class_ops { int (*read_alarm)(struct device *, struct rtc_wkalrm *); int (*set_alarm)(struct device *, struct rtc_wkalrm *); int (*proc)(struct device *, struct seq_file *); - int (*set_mmss64)(struct device *, time64_t secs); - int (*set_mmss)(struct device *, unsigned long secs); int (*alarm_irq_enable)(struct device *, unsigned int enabled); int (*read_offset)(struct device *, long *offset); int (*set_offset)(struct device *, long offset); @@ -162,9 +160,11 @@ struct rtc_device { #define to_rtc_device(d) container_of(d, struct rtc_device, dev) /* useful timestamps */ -#define RTC_TIMESTAMP_BEGIN_1900 -2208989361LL /* 1900-01-01 00:00:00 */ +#define RTC_TIMESTAMP_BEGIN_1900 -2208988800LL /* 1900-01-01 00:00:00 */ #define RTC_TIMESTAMP_BEGIN_2000 946684800LL /* 2000-01-01 00:00:00 */ +#define RTC_TIMESTAMP_END_2063 2966371199LL /* 2063-12-31 23:59:59 */ #define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */ +#define RTC_TIMESTAMP_END_9999 253402300799LL /* 9999-12-31 23:59:59 */ extern struct rtc_device *devm_rtc_device_register(struct device *dev, const char *name, diff --git a/include/linux/rtc/ds1685.h b/include/linux/rtc/ds1685.h index e6337a56d741..a00b332c505f 100644 --- a/include/linux/rtc/ds1685.h +++ b/include/linux/rtc/ds1685.h @@ -48,8 +48,6 @@ struct ds1685_priv { u32 regstep; resource_size_t baseaddr; size_t size; - spinlock_t lock; - struct work_struct work; int irq_num; bool bcd_mode; bool no_irq; |