diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 20:22:27 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-10 20:22:27 +0300 |
commit | fbe173e3ffbd897b5a859020d714c0eaf4af2a1a (patch) | |
tree | 602fd9da34454d934fcee56b8a74ebed05ba7d1c | |
parent | 5e630afdcb82779f5bf03fd4a5e86adc56fe7c8a (diff) | |
parent | 1485991c024603b2fb4ae77beb7a0d741128a48e (diff) | |
download | linux-fbe173e3ffbd897b5a859020d714c0eaf4af2a1a.tar.xz |
Merge tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"This contains a few series that have been in preparation for a while
and that will help systems with RTCs that will fail in 2038, 2069 or
2100.
Subsystem:
- Add tracepoints
- Rework of the RTC/nvmem API to allow drivers to discard struct
nvmem_config after registration
- New range API, drivers can now expose the useful range of the RTC
- New offset API the core is now able to add an offset to the RTC
time, modifying the supported range.
- Multiple rtc_time64_to_tm fixes
- Handle time_t overflow on 32 bit platforms in the core instead of
letting drivers do crazy things.
- remove rtc_control API
New driver:
- Intersil ISL12026
Drivers:
- Drivers exposing the RTC non volatile memory have been converted to
use nvmem
- Removed useless time and date validation
- Removed an indirection pattern that was a cargo cult from ancient
drivers
- Removed VLA usage
- Fixed a possible race condition in probe functions
- AB8540 support is dropped from ab8500
- pcf85363 now has alarm support"
* tag 'rtc-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (128 commits)
rtc: snvs: Fix usage of snvs_rtc_enable
rtc: mt7622: fix module autoloading for OF platform drivers
rtc: isl12022: use true and false for boolean values
rtc: ab8500: Drop AB8540 support
rtc: remove a warning during scripts/kernel-doc step
rtc: 88pm860x: remove artificial limitation
rtc: 88pm80x: remove artificial limitation
rtc: st-lpc: remove artificial limitation
rtc: mrst: remove artificial limitation
rtc: mv: remove artificial limitation
rtc: hctosys: Ensure system time doesn't overflow time_t
parisc: time: stop validating rtc_time in .read_time
rtc: pcf85063: fix clearing bits in pcf85063_start_clock
rtc: at91sam9: Set name of regmap_config
rtc: s5m: Remove VLA usage
rtc: s5m: Move enum from rtc.h to rtc-s5m.c
rtc: remove VLA usage
rtc: Add useful timestamp definitions
rtc: Add one offset seconds to expand RTC range
rtc: Factor out the RTC range validation into rtc_valid_range()
...
123 files changed, 1810 insertions, 1084 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-rtc b/Documentation/ABI/testing/sysfs-class-rtc index cf60412882f0..95984289a4ee 100644 --- a/Documentation/ABI/testing/sysfs-class-rtc +++ b/Documentation/ABI/testing/sysfs-class-rtc @@ -43,6 +43,14 @@ Contact: linux-rtc@vger.kernel.org Description: (RO) The name of the RTC corresponding to this sysfs directory +What: /sys/class/rtc/rtcX/range +Date: January 2018 +KernelVersion: 4.16 +Contact: linux-rtc@vger.kernel.org +Description: + Valid time range for the RTC, as seconds from epoch, formatted + as [min, max] + What: /sys/class/rtc/rtcX/since_epoch Date: March 2006 KernelVersion: 2.6.17 @@ -57,14 +65,6 @@ Contact: linux-rtc@vger.kernel.org Description: (RO) RTC-provided time in 24-hour notation (hh:mm:ss) -What: /sys/class/rtc/rtcX/*/nvmem -Date: February 2016 -KernelVersion: 4.6 -Contact: linux-rtc@vger.kernel.org -Description: - (RW) The non volatile storage exported as a raw file, as - described in Documentation/nvmem/nvmem.txt - What: /sys/class/rtc/rtcX/offset Date: February 2016 KernelVersion: 4.6 diff --git a/Documentation/devicetree/bindings/rtc/isil,isl12026.txt b/Documentation/devicetree/bindings/rtc/isil,isl12026.txt new file mode 100644 index 000000000000..2e0be45193bb --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/isil,isl12026.txt @@ -0,0 +1,28 @@ +ISL12026 I2C RTC/EEPROM + +ISL12026 is an I2C RTC/EEPROM combination device. The RTC and control +registers respond at bus address 0x6f, and the EEPROM array responds +at bus address 0x57. The canonical "reg" value will be for the RTC portion. + +Required properties supported by the device: + + - "compatible": must be "isil,isl12026" + - "reg": I2C bus address of the device (always 0x6f) + +Optional properties: + + - "isil,pwr-bsw": If present PWR.BSW bit must be set to the specified + value for proper operation. + + - "isil,pwr-sbib": If present PWR.SBIB bit must be set to the specified + value for proper operation. + + +Example: + + rtc@6f { + compatible = "isil,isl12026"; + reg = <0x6f>; + isil,pwr-bsw = <0>; + isil,pwr-sbib = <1>; + } diff --git a/MAINTAINERS b/MAINTAINERS index 6d296bdce328..dd7ce9171ac0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11810,7 +11810,7 @@ X: kernel/torture.c REAL TIME CLOCK (RTC) SUBSYSTEM M: Alessandro Zummo <a.zummo@towertech.it> -M: Alexandre Belloni <alexandre.belloni@free-electrons.com> +M: Alexandre Belloni <alexandre.belloni@bootlin.com> L: linux-rtc@vger.kernel.org Q: http://patchwork.ozlabs.org/project/rtc-linux/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux.git diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index f7e684560186..c3830400ca28 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -174,7 +174,7 @@ static int rtc_generic_get_time(struct device *dev, struct rtc_time *tm) /* we treat tod_sec as unsigned, so this can work until year 2106 */ rtc_time64_to_tm(tod_data.tod_sec, tm); - return rtc_valid_tm(tm); + return 0; } static int rtc_generic_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 0c858d027bf3..57dc546628b5 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -809,89 +809,6 @@ static __poll_t rtc_poll(struct file *file, poll_table *wait) } #endif -int rtc_register(rtc_task_t *task) -{ -#ifndef RTC_IRQ - return -EIO; -#else - if (task == NULL || task->func == NULL) - return -EINVAL; - spin_lock_irq(&rtc_lock); - if (rtc_status & RTC_IS_OPEN) { - spin_unlock_irq(&rtc_lock); - return -EBUSY; - } - spin_lock(&rtc_task_lock); - if (rtc_callback) { - spin_unlock(&rtc_task_lock); - spin_unlock_irq(&rtc_lock); - return -EBUSY; - } - rtc_status |= RTC_IS_OPEN; - rtc_callback = task; - spin_unlock(&rtc_task_lock); - spin_unlock_irq(&rtc_lock); - return 0; -#endif -} -EXPORT_SYMBOL(rtc_register); - -int rtc_unregister(rtc_task_t *task) -{ -#ifndef RTC_IRQ - return -EIO; -#else - unsigned char tmp; - - spin_lock_irq(&rtc_lock); - spin_lock(&rtc_task_lock); - if (rtc_callback != task) { - spin_unlock(&rtc_task_lock); - spin_unlock_irq(&rtc_lock); - return -ENXIO; - } - rtc_callback = NULL; - - /* disable controls */ - if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) { - tmp = CMOS_READ(RTC_CONTROL); - tmp &= ~RTC_PIE; - tmp &= ~RTC_AIE; - tmp &= ~RTC_UIE; - CMOS_WRITE(tmp, RTC_CONTROL); - CMOS_READ(RTC_INTR_FLAGS); - } - if (rtc_status & RTC_TIMER_ON) { - rtc_status &= ~RTC_TIMER_ON; - del_timer(&rtc_irq_timer); - } - rtc_status &= ~RTC_IS_OPEN; - spin_unlock(&rtc_task_lock); - spin_unlock_irq(&rtc_lock); - return 0; -#endif -} -EXPORT_SYMBOL(rtc_unregister); - -int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg) -{ -#ifndef RTC_IRQ - return -EIO; -#else - unsigned long flags; - if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET) - return -EINVAL; - spin_lock_irqsave(&rtc_task_lock, flags); - if (rtc_callback != task) { - spin_unlock_irqrestore(&rtc_task_lock, flags); - return -ENXIO; - } - spin_unlock_irqrestore(&rtc_task_lock, flags); - return rtc_do_ioctl(cmd, arg, 1); -#endif -} -EXPORT_SYMBOL(rtc_control); - /* * The various file operations we support. */ diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 319e3c8976d5..59e6dede3db3 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -407,6 +407,16 @@ config RTC_DRV_ISL12022 This driver can also be built as a module. If so, the module will be called rtc-isl12022. +config RTC_DRV_ISL12026 + tristate "Intersil ISL12026" + depends on OF || COMPILE_TEST + help + If you say yes here you get support for the + Intersil ISL12026 RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-isl12026. + config RTC_DRV_X1205 tristate "Xicor/Intersil X1205" help @@ -1413,6 +1423,7 @@ config RTC_DRV_AT91RM9200 config RTC_DRV_AT91SAM9 tristate "AT91SAM9 RTT as RTC" depends on ARCH_AT91 || COMPILE_TEST + depends on HAS_IOMEM select MFD_SYSCON help Some AT91SAM9 SoCs provide an RTT (Real Time Timer) block which @@ -1502,7 +1513,7 @@ config RTC_DRV_STARFIRE config RTC_DRV_TX4939 tristate "TX4939 SoC" - depends on SOC_TX4939 + depends on SOC_TX4939 || COMPILE_TEST help Driver for the internal RTC (Realtime Clock) module found on Toshiba TX4939 SoC. diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ee0206becd9f..5ff2fc0c361a 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -75,6 +75,7 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o obj-$(CONFIG_RTC_DRV_HYM8563) += rtc-hym8563.o obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o +obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o obj-$(CONFIG_RTC_DRV_LP8788) += rtc-lp8788.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 722d683e0b0f..d37588f08055 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -211,6 +211,73 @@ static int rtc_device_get_id(struct device *dev) return id; } +static void rtc_device_get_offset(struct rtc_device *rtc) +{ + time64_t range_secs; + u32 start_year; + int ret; + + /* + * If RTC driver did not implement the range of RTC hardware device, + * then we can not expand the RTC range by adding or subtracting one + * offset. + */ + if (rtc->range_min == rtc->range_max) + return; + + ret = device_property_read_u32(rtc->dev.parent, "start-year", + &start_year); + if (!ret) { + rtc->start_secs = mktime64(start_year, 1, 1, 0, 0, 0); + rtc->set_start_time = true; + } + + /* + * If user did not implement the start time for RTC driver, then no + * need to expand the RTC range. + */ + if (!rtc->set_start_time) + return; + + range_secs = rtc->range_max - rtc->range_min + 1; + + /* + * If the start_secs is larger than the maximum seconds (rtc->range_max) + * supported by RTC hardware or the maximum seconds of new expanded + * range (start_secs + rtc->range_max - rtc->range_min) is less than + * rtc->range_min, which means the minimum seconds (rtc->range_min) of + * RTC hardware will be mapped to start_secs by adding one offset, so + * the offset seconds calculation formula should be: + * rtc->offset_secs = rtc->start_secs - rtc->range_min; + * + * If the start_secs is larger than the minimum seconds (rtc->range_min) + * supported by RTC hardware, then there is one region is overlapped + * between the original RTC hardware range and the new expanded range, + * and this overlapped region do not need to be mapped into the new + * expanded range due to it is valid for RTC device. So the minimum + * seconds of RTC hardware (rtc->range_min) should be mapped to + * rtc->range_max + 1, then the offset seconds formula should be: + * rtc->offset_secs = rtc->range_max - rtc->range_min + 1; + * + * If the start_secs is less than the minimum seconds (rtc->range_min), + * which is similar to case 2. So the start_secs should be mapped to + * start_secs + rtc->range_max - rtc->range_min + 1, then the + * offset seconds formula should be: + * rtc->offset_secs = -(rtc->range_max - rtc->range_min + 1); + * + * Otherwise the offset seconds should be 0. + */ + if (rtc->start_secs > rtc->range_max || + rtc->start_secs + range_secs - 1 < rtc->range_min) + rtc->offset_secs = rtc->start_secs - rtc->range_min; + else if (rtc->start_secs > rtc->range_min) + rtc->offset_secs = range_secs; + else if (rtc->start_secs < rtc->range_min) + rtc->offset_secs = -range_secs; + else + rtc->offset_secs = 0; +} + /** * rtc_device_register - register w/ RTC class * @dev: the device to register @@ -247,6 +314,8 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, dev_set_name(&rtc->dev, "rtc%d", id); + rtc_device_get_offset(rtc); + /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); @@ -293,8 +362,6 @@ EXPORT_SYMBOL_GPL(rtc_device_register); */ void rtc_device_unregister(struct rtc_device *rtc) { - rtc_nvmem_unregister(rtc); - mutex_lock(&rtc->ops_lock); /* * Remove innards of this RTC, then disable it, before @@ -312,6 +379,7 @@ static void devm_rtc_device_release(struct device *dev, void *res) { struct rtc_device *rtc = *(struct rtc_device **)res; + rtc_nvmem_unregister(rtc); rtc_device_unregister(rtc); } @@ -382,6 +450,8 @@ static void devm_rtc_release_device(struct device *dev, void *res) { struct rtc_device *rtc = *(struct rtc_device **)res; + rtc_nvmem_unregister(rtc); + if (rtc->registered) rtc_device_unregister(rtc); else @@ -435,6 +505,7 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) return -EINVAL; rtc->owner = owner; + rtc_device_get_offset(rtc); /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); @@ -453,8 +524,6 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) rtc_proc_add_device(rtc); - rtc_nvmem_register(rtc); - rtc->registered = true; dev_info(rtc->dev.parent, "registered as %s\n", dev_name(&rtc->dev)); diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c index e1cfa06810ef..e79f2a181ad2 100644 --- a/drivers/rtc/hctosys.c +++ b/drivers/rtc/hctosys.c @@ -49,6 +49,11 @@ static int __init rtc_hctosys(void) tv64.tv_sec = rtc_tm_to_time64(&tm); +#if BITS_PER_LONG == 32 + if (tv64.tv_sec > INT_MAX) + goto err_read; +#endif + err = do_settimeofday64(&tv64); dev_info(rtc->dev.parent, diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 672b192f8153..7cbdc9228dd5 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -17,9 +17,73 @@ #include <linux/log2.h> #include <linux/workqueue.h> +#define CREATE_TRACE_POINTS +#include <trace/events/rtc.h> + static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); +static void rtc_add_offset(struct rtc_device *rtc, struct rtc_time *tm) +{ + time64_t secs; + + if (!rtc->offset_secs) + return; + + secs = rtc_tm_to_time64(tm); + + /* + * Since the reading time values from RTC device are always in the RTC + * original valid range, but we need to skip the overlapped region + * between expanded range and original range, which is no need to add + * the offset. + */ + if ((rtc->start_secs > rtc->range_min && secs >= rtc->start_secs) || + (rtc->start_secs < rtc->range_min && + secs <= (rtc->start_secs + rtc->range_max - rtc->range_min))) + return; + + rtc_time64_to_tm(secs + rtc->offset_secs, tm); +} + +static void rtc_subtract_offset(struct rtc_device *rtc, struct rtc_time *tm) +{ + time64_t secs; + + if (!rtc->offset_secs) + return; + + secs = rtc_tm_to_time64(tm); + + /* + * If the setting time values are in the valid range of RTC hardware + * device, then no need to subtract the offset when setting time to RTC + * device. Otherwise we need to subtract the offset to make the time + * values are valid for RTC hardware device. + */ + if (secs >= rtc->range_min && secs <= rtc->range_max) + return; + + rtc_time64_to_tm(secs - rtc->offset_secs, tm); +} + +static int rtc_valid_range(struct rtc_device *rtc, struct rtc_time *tm) +{ + if (rtc->range_min != rtc->range_max) { + time64_t time = rtc_tm_to_time64(tm); + time64_t range_min = rtc->set_start_time ? rtc->start_secs : + rtc->range_min; + time64_t range_max = rtc->set_start_time ? + (rtc->start_secs + rtc->range_max - rtc->range_min) : + rtc->range_max; + + if (time < range_min || time > range_max) + return -ERANGE; + } + + return 0; +} + static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) { int err; @@ -36,6 +100,8 @@ static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) return err; } + rtc_add_offset(rtc, tm); + err = rtc_valid_tm(tm); if (err < 0) dev_dbg(&rtc->dev, "read_time: rtc_time isn't valid\n"); @@ -53,6 +119,8 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) err = __rtc_read_time(rtc, tm); mutex_unlock(&rtc->ops_lock); + + trace_rtc_read_time(rtc_tm_to_time64(tm), err); return err; } EXPORT_SYMBOL_GPL(rtc_read_time); @@ -65,6 +133,12 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) if (err != 0) return err; + err = rtc_valid_range(rtc, tm); + if (err) + return err; + + rtc_subtract_offset(rtc, tm); + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -87,6 +161,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) mutex_unlock(&rtc->ops_lock); /* A timer might have just expired */ schedule_work(&rtc->irqwork); + + trace_rtc_set_time(rtc_tm_to_time64(tm), err); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -119,6 +195,8 @@ static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *al } mutex_unlock(&rtc->ops_lock); + + trace_rtc_read_alarm(rtc_tm_to_time64(&alarm->time), err); return err; } @@ -316,6 +394,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } mutex_unlock(&rtc->ops_lock); + trace_rtc_read_alarm(rtc_tm_to_time64(&alarm->time), err); return err; } EXPORT_SYMBOL_GPL(rtc_read_alarm); @@ -329,6 +408,8 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = rtc_valid_tm(&alarm->time); if (err) return err; + + rtc_subtract_offset(rtc, &alarm->time); scheduled = rtc_tm_to_time64(&alarm->time); /* Make sure we're not setting alarms in the past */ @@ -352,6 +433,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + trace_rtc_set_alarm(rtc_tm_to_time64(&alarm->time), err); return err; } @@ -363,6 +445,10 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) if (err != 0) return err; + err = rtc_valid_range(rtc, &alarm->time); + if (err) + return err; + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; @@ -375,6 +461,8 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = rtc_timer_enqueue(rtc, &rtc->aie_timer); mutex_unlock(&rtc->ops_lock); + + rtc_add_offset(rtc, &alarm->time); return err; } EXPORT_SYMBOL_GPL(rtc_set_alarm); @@ -406,6 +494,7 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) rtc->aie_timer.enabled = 1; timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); + trace_rtc_timer_enqueue(&rtc->aie_timer); } mutex_unlock(&rtc->ops_lock); return err; @@ -435,6 +524,8 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) err = rtc->ops->alarm_irq_enable(rtc->dev.parent, enabled); mutex_unlock(&rtc->ops_lock); + + trace_rtc_alarm_irq_enable(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_alarm_irq_enable); @@ -709,6 +800,8 @@ retry: rtc->pie_enabled = enabled; } spin_unlock_irqrestore(&rtc->irq_task_lock, flags); + + trace_rtc_irq_set_state(enabled, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_state); @@ -745,6 +838,8 @@ retry: } } spin_unlock_irqrestore(&rtc->irq_task_lock, flags); + + trace_rtc_irq_set_freq(freq, err); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_freq); @@ -779,6 +874,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) } timerqueue_add(&rtc->timerqueue, &timer->node); + trace_rtc_timer_enqueue(timer); if (!next || ktime_before(timer->node.expires, next->expires)) { struct rtc_wkalrm alarm; int err; @@ -790,6 +886,7 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) schedule_work(&rtc->irqwork); } else if (err) { timerqueue_del(&rtc->timerqueue, &timer->node); + trace_rtc_timer_dequeue(timer); timer->enabled = 0; return err; } @@ -803,6 +900,7 @@ static void rtc_alarm_disable(struct rtc_device *rtc) return; rtc->ops->alarm_irq_enable(rtc->dev.parent, false); + trace_rtc_alarm_irq_enable(0, 0); } /** @@ -821,6 +919,7 @@ 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; @@ -871,16 +970,19 @@ again: /* expire timer */ timer = container_of(next, struct rtc_timer, node); timerqueue_del(&rtc->timerqueue, &timer->node); + trace_rtc_timer_dequeue(timer); timer->enabled = 0; if (timer->task.func) timer->task.func(timer->task.private_data); + trace_rtc_timer_fired(timer); /* Re-add/fwd periodic timers */ if (ktime_to_ns(timer->period)) { timer->node.expires = ktime_add(timer->node.expires, timer->period); timer->enabled = 1; timerqueue_add(&rtc->timerqueue, &timer->node); + trace_rtc_timer_enqueue(timer); } } @@ -902,6 +1004,7 @@ reprogram: timer = container_of(next, struct rtc_timer, node); timerqueue_del(&rtc->timerqueue, &timer->node); + trace_rtc_timer_dequeue(timer); timer->enabled = 0; dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err); goto again; @@ -992,6 +1095,8 @@ int rtc_read_offset(struct rtc_device *rtc, long *offset) mutex_lock(&rtc->ops_lock); ret = rtc->ops->read_offset(rtc->dev.parent, offset); mutex_unlock(&rtc->ops_lock); + + trace_rtc_read_offset(*offset, ret); return ret; } @@ -1025,5 +1130,7 @@ int rtc_set_offset(struct rtc_device *rtc, long offset) mutex_lock(&rtc->ops_lock); ret = rtc->ops->set_offset(rtc->dev.parent, offset); mutex_unlock(&rtc->ops_lock); + + trace_rtc_set_offset(offset, ret); return ret; } diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index 8567b4ed9ac6..17ec4c8d0fad 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -14,8 +14,6 @@ #include <linux/rtc.h> #include <linux/sysfs.h> -#include "rtc-core.h" - /* * Deprecated ABI compatibility, this should be removed at some point */ @@ -46,7 +44,7 @@ rtc_nvram_write(struct file *filp, struct kobject *kobj, return nvmem_device_write(rtc->nvmem, off, count, buf); } -static int rtc_nvram_register(struct rtc_device *rtc) +static int rtc_nvram_register(struct rtc_device *rtc, size_t size) { int err; @@ -64,7 +62,7 @@ static int rtc_nvram_register(struct rtc_device *rtc) rtc->nvram->read = rtc_nvram_read; rtc->nvram->write = rtc_nvram_write; - rtc->nvram->size = rtc->nvmem_config->size; + rtc->nvram->size = size; err = sysfs_create_bin_file(&rtc->dev.parent->kobj, rtc->nvram); @@ -84,21 +82,28 @@ static void rtc_nvram_unregister(struct rtc_device *rtc) /* * New ABI, uses nvmem */ -void rtc_nvmem_register(struct rtc_device *rtc) +int rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config) { - if (!rtc->nvmem_config) - return; + if (!IS_ERR_OR_NULL(rtc->nvmem)) + return -EBUSY; + + if (!nvmem_config) + return -ENODEV; - rtc->nvmem_config->dev = &rtc->dev; - rtc->nvmem_config->owner = rtc->owner; - rtc->nvmem = nvmem_register(rtc->nvmem_config); + nvmem_config->dev = rtc->dev.parent; + nvmem_config->owner = rtc->owner; + rtc->nvmem = nvmem_register(nvmem_config); if (IS_ERR_OR_NULL(rtc->nvmem)) - return; + return PTR_ERR(rtc->nvmem); /* Register the old ABI */ if (rtc->nvram_old_abi) - rtc_nvram_register(rtc); + rtc_nvram_register(rtc, nvmem_config->size); + + return 0; } +EXPORT_SYMBOL_GPL(rtc_nvmem_register); void rtc_nvmem_unregister(struct rtc_device *rtc) { diff --git a/drivers/rtc/rtc-88pm80x.c b/drivers/rtc/rtc-88pm80x.c index 466bf7f9a285..6cbafefa80a2 100644 --- a/drivers/rtc/rtc-88pm80x.c +++ b/drivers/rtc/rtc-88pm80x.c @@ -134,9 +134,9 @@ static int pm80x_rtc_set_time(struct device *dev, struct rtc_time *tm) struct pm80x_rtc_info *info = dev_get_drvdata(dev); unsigned char buf[4]; unsigned long ticks, base, data; - if ((tm->tm_year < 70) || (tm->tm_year > 138)) { + if (tm->tm_year > 206) { dev_dbg(info->dev, - "Set time %d out of range. Please set time between 1970 to 2038.\n", + "Set time %d out of range. Please set time between 1970 to 2106.\n", 1900 + tm->tm_year); return -EINVAL; } diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 19e53b3b8e00..01ffc0ef8033 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -135,9 +135,9 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned char buf[4]; unsigned long ticks, base, data; - if ((tm->tm_year < 70) || (tm->tm_year > 138)) { + if (tm->tm_year > 206) { dev_dbg(info->dev, "Set time %d out of range. " - "Please set time between 1970 to 2038.\n", + "Please set time between 1970 to 2106.\n", 1900 + tm->tm_year); return -EINVAL; } diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index ef5c16dfabfa..8dc451932446 100644 --- a/drivers/rtc/rtc-ab-b5ze-s3.c +++ b/drivers/rtc/rtc-ab-b5ze-s3.c @@ -217,7 +217,7 @@ static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct abb5zes3_rtc_data *data = dev_get_drvdata(dev); u8 regs[ABB5ZES3_REG_RTC_SC + ABB5ZES3_RTC_SEC_LEN]; - int ret; + int ret = 0; /* * As we need to read CTRL1 register anyway to access 24/12h @@ -255,8 +255,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; - ret = rtc_valid_tm(tm); - err: return ret; } diff --git a/drivers/rtc/rtc-ab3100.c b/drivers/rtc/rtc-ab3100.c index 9b725c553058..821ff52a2222 100644 --- a/drivers/rtc/rtc-ab3100.c +++ b/drivers/rtc/rtc-ab3100.c @@ -106,7 +106,7 @@ static int ab3100_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time64_to_tm(time, tm); - return rtc_valid_tm(tm); + return 0; } static int ab3100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 24a0af650a1b..e28f4401fd35 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -36,10 +36,6 @@ #define AB8500_RTC_FORCE_BKUP_REG 0x0D #define AB8500_RTC_CALIB_REG 0x0E #define AB8500_RTC_SWITCH_STAT_REG 0x0F -#define AB8540_RTC_ALRM_SEC 0x22 -#define AB8540_RTC_ALRM_MIN_LOW_REG 0x23 -#define AB8540_RTC_ALRM_MIN_MID_REG 0x24 -#define AB8540_RTC_ALRM_MIN_HI_REG 0x25 /* RtcReadRequest bits */ #define RTC_READ_REQUEST 0x01 @@ -63,11 +59,6 @@ static const u8 ab8500_rtc_alarm_regs[] = { AB8500_RTC_ALRM_MIN_LOW_REG }; -static const u8 ab8540_rtc_alarm_regs[] = { - AB8540_RTC_ALRM_MIN_HI_REG, AB8540_RTC_ALRM_MIN_MID_REG, - AB8540_RTC_ALRM_MIN_LOW_REG, AB8540_RTC_ALRM_SEC -}; - /* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ static unsigned long get_elapsed_seconds(int year) { @@ -131,7 +122,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) secs += get_elapsed_seconds(AB8500_RTC_EPOCH); rtc_time_to_tm(secs, tm); - return rtc_valid_tm(tm); + return 0; } static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -277,43 +268,6 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return ab8500_rtc_irq_enable(dev, alarm->enabled); } -static int ab8540_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) -{ - int retval, i; - unsigned char buf[ARRAY_SIZE(ab8540_rtc_alarm_regs)]; - unsigned long mins, secs = 0; - - if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { - dev_dbg(dev, "year should be equal to or greater than %d\n", - AB8500_RTC_EPOCH); - return -EINVAL; - } - - /* Get the number of seconds since 1970 */ - rtc_tm_to_time(&alarm->time, &secs); - - /* - * Convert it to the number of seconds since 01-01-2000 00:00:00 - */ - secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); - mins = secs / 60; - - buf[3] = secs % 60; - buf[2] = mins & 0xFF; - buf[1] = (mins >> 8) & 0xFF; - buf[0] = (mins >> 16) & 0xFF; - - /* Set the alarm time */ - for (i = 0; i < ARRAY_SIZE(ab8540_rtc_alarm_regs); i++) { - retval = abx500_set_register_interruptible(dev, AB8500_RTC, - ab8540_rtc_alarm_regs[i], buf[i]); - if (retval < 0) - return retval; - } - - return ab8500_rtc_irq_enable(dev, alarm->enabled); -} - static int ab8500_rtc_set_calibration(struct device *dev, int calibration) { int retval; @@ -435,17 +389,8 @@ static const struct rtc_class_ops ab8500_rtc_ops = { .alarm_irq_enable = ab8500_rtc_irq_enable, }; -static const struct rtc_class_ops ab8540_rtc_ops = { - .read_time = ab8500_rtc_read_time, - .set_time = ab8500_rtc_set_time, - .read_alarm = ab8500_rtc_read_alarm, - .set_alarm = ab8540_rtc_set_alarm, - .alarm_irq_enable = ab8500_rtc_irq_enable, -}; - static const struct platform_device_id ab85xx_rtc_ids[] = { { "ab8500-rtc", (kernel_ulong_t)&ab8500_rtc_ops, }, - { "ab8540-rtc", (kernel_ulong_t)&ab8540_rtc_ops, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(platform, ab85xx_rtc_ids); diff --git a/drivers/rtc/rtc-abx80x.c b/drivers/rtc/rtc-abx80x.c index b033bc556f5d..2cefa67a1132 100644 --- a/drivers/rtc/rtc-abx80x.c +++ b/drivers/rtc/rtc-abx80x.c @@ -172,11 +172,7 @@ static int abx80x_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F) - 1; tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 100; - err = rtc_valid_tm(tm); - if (err < 0) - dev_err(&client->dev, "retrieved date/time is not valid.\n"); - - return err; + return 0; } static int abx80x_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 8ff9dc3fe5bf..3fe576fdd45e 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -183,7 +183,29 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw, for (i = 0; i < num_parents; i++) { struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); - unsigned long tmp, prate = clk_hw_get_rate(parent); + unsigned long tmp, prate; + + /* + * The clock has two parents, one is a fixed clock which is + * internally registered by the ac100 driver. The other parent + * is a clock from the codec side of the chip, which we + * properly declare and reference in the devicetree and is + * not implemented in any driver right now. + * If the clock core looks for the parent of that second + * missing clock, it can't find one that is registered and + * returns NULL. + * So we end up in a situation where clk_hw_get_num_parents + * returns the amount of clocks we can be parented to, but + * clk_hw_get_parent_by_index will not return the orphan + * clocks. + * Thus we need to check if the parent exists before + * we get the parent rate, so we could use the RTC + * without waiting for the codec to be supported. + */ + if (!parent) + continue; + + prate = clk_hw_get_rate(parent); tmp = ac100_clkout_round_rate(hw, req->rate, prate); @@ -387,7 +409,7 @@ static int ac100_rtc_get_time(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_year = bcd2bin(reg[6] & AC100_RTC_YEA_MASK) + AC100_YEAR_OFF; - return rtc_valid_tm(rtc_tm); + return 0; } static int ac100_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index 7418a763ce52..ee71e647fd43 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -349,6 +349,7 @@ static const struct rtc_class_ops at91_rtc_ops = { }; static const struct regmap_config gpbr_regmap_config = { + .name = "gpbr", .reg_bits = 32, .val_bits = 32, .reg_stride = 4, diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index 2ba44ccb9c3a..7c5530c71285 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -36,7 +36,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time_to_tm(t, tm); - return rtc_valid_tm(tm); + return 0; } static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 98ac8d5c7901..ef52741000a8 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -36,6 +36,10 @@ #define BQ32K_CFG2 0x09 /* Trickle charger control */ #define BQ32K_TCFE BIT(6) /* Trickle charge FET bypass */ +#define MAX_LEN 10 /* Maximum number of consecutive + * register for this particular RTC. + */ + struct bq32k_regs { uint8_t seconds; uint8_t minutes; @@ -74,7 +78,7 @@ static int bq32k_read(struct device *dev, void *data, uint8_t off, uint8_t len) static int bq32k_write(struct device *dev, void *data, uint8_t off, uint8_t len) { struct i2c_client *client = to_i2c_client(dev); - uint8_t buffer[len + 1]; + uint8_t buffer[MAX_LEN + 1]; buffer[0] = off; memcpy(&buffer[1], data, len); @@ -110,7 +114,7 @@ static int bq32k_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_year = bcd2bin(regs.years) + ((regs.cent_hours & BQ32K_CENT) ? 100 : 0); - return rtc_valid_tm(tm); + return 0; } static int bq32k_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c index 6cee61201c30..bdd6674a1054 100644 --- a/drivers/rtc/rtc-brcmstb-waketimer.c +++ b/drivers/rtc/rtc-brcmstb-waketimer.c @@ -60,6 +60,9 @@ static void brcmstb_waketmr_set_alarm(struct brcmstb_waketmr *timer, { brcmstb_waketmr_clear_alarm(timer); + /* Make sure we are actually counting in seconds */ + writel_relaxed(timer->rate, timer->base + BRCMSTB_WKTMR_PRESCALER); + writel_relaxed(secs + 1, timer->base + BRCMSTB_WKTMR_ALARM); } diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index f7c0f72abb56..1b3738a11702 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -541,11 +541,10 @@ static const struct rtc_class_ops cmos_rtc_ops = { #define NVRAM_OFFSET (RTC_REG_D + 1) -static ssize_t -cmos_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int cmos_nvram_read(void *priv, unsigned int off, void *val, + size_t count) { + unsigned char *buf = val; int retval; off += NVRAM_OFFSET; @@ -563,16 +562,13 @@ cmos_nvram_read(struct file *filp, struct kobject *kobj, return retval; } -static ssize_t -cmos_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int cmos_nvram_write(void *priv, unsigned int off, void *val, + size_t count) { - struct cmos_rtc *cmos; + struct cmos_rtc *cmos = priv; + unsigned char *buf = val; int retval; - cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); - /* NOTE: on at least PCs and Ataris, the boot firmware uses a * checksum on part of the NVRAM data. That's currently ignored * here. If userspace is smart enough to know what fields of @@ -598,17 +594,6 @@ cmos_nvram_write(struct file *filp, struct kobject *kobj, return retval; } -static struct bin_attribute nvram = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - - .read = cmos_nvram_read, - .write = cmos_nvram_write, - /* size gets set up later */ -}; - /*----------------------------------------------------------------*/ static struct cmos_rtc cmos_rtc; @@ -675,6 +660,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) unsigned char rtc_control; unsigned address_space; u32 flags = 0; + struct nvmem_config nvmem_cfg = { + .name = "cmos_nvram", + .word_size = 1, + .stride = 1, + .reg_read = cmos_nvram_read, + .reg_write = cmos_nvram_write, + .priv = &cmos_rtc, + }; /* there can be only one ... */ if (cmos_rtc.dev) @@ -751,8 +744,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) cmos_rtc.dev = dev; dev_set_drvdata(dev, &cmos_rtc); - cmos_rtc.rtc = rtc_device_register(driver_name, dev, - &cmos_rtc_ops, THIS_MODULE); + cmos_rtc.rtc = devm_rtc_allocate_device(dev); if (IS_ERR(cmos_rtc.rtc)) { retval = PTR_ERR(cmos_rtc.rtc); goto cleanup0; @@ -814,22 +806,25 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) } } - /* export at least the first block of NVRAM */ - nvram.size = address_space - NVRAM_OFFSET; - retval = sysfs_create_bin_file(&dev->kobj, &nvram); - if (retval < 0) { - dev_dbg(dev, "can't create nvram file? %d\n", retval); + cmos_rtc.rtc->ops = &cmos_rtc_ops; + cmos_rtc.rtc->nvram_old_abi = true; + retval = rtc_register_device(cmos_rtc.rtc); + if (retval) goto cleanup2; - } - dev_info(dev, "%s%s, %zd bytes nvram%s\n", - !is_valid_irq(rtc_irq) ? "no alarms" : - cmos_rtc.mon_alrm ? "alarms up to one year" : - cmos_rtc.day_alrm ? "alarms up to one month" : - "alarms up to one day", - cmos_rtc.century ? ", y3k" : "", - nvram.size, - is_hpet_enabled() ? ", hpet irqs" : ""); + /* export at least the first block of NVRAM */ + nvmem_cfg.size = address_space - NVRAM_OFFSET; + if (rtc_nvmem_register(cmos_rtc.rtc, &nvmem_cfg)) + dev_err(dev, "nvmem registration failed\n"); + + dev_info(dev, "%s%s, %d bytes nvram%s\n", + !is_valid_irq(rtc_irq) ? "no alarms" : + cmos_rtc.mon_alrm ? "alarms up to one year" : + cmos_rtc.day_alrm ? "alarms up to one month" : + "alarms up to one day", + cmos_rtc.century ? ", y3k" : "", + nvmem_cfg.size, + is_hpet_enabled() ? ", hpet irqs" : ""); return 0; @@ -838,7 +833,6 @@ cleanup2: free_irq(rtc_irq, cmos_rtc.rtc); cleanup1: cmos_rtc.dev = NULL; - rtc_device_unregister(cmos_rtc.rtc); cleanup0: if (RTC_IOMAPPED) release_region(ports->start, resource_size(ports)); @@ -862,14 +856,11 @@ static void cmos_do_remove(struct device *dev) cmos_do_shutdown(cmos->irq); - sysfs_remove_bin_file(&dev->kobj, &nvram); - if (is_valid_irq(cmos->irq)) { free_irq(cmos->irq, cmos->rtc); hpet_unregister_irq_handler(cmos_interrupt); } - rtc_device_unregister(cmos->rtc); cmos->rtc = NULL; ports = cmos->iomem; @@ -1271,8 +1262,6 @@ MODULE_DEVICE_TABLE(of, of_cmos_match); static __init void cmos_of_init(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct rtc_time time; - int ret; const __be32 *val; if (!node) @@ -1285,16 +1274,6 @@ static __init void cmos_of_init(struct platform_device *pdev) val = of_get_property(node, "freq-reg", NULL); if (val) CMOS_WRITE(be32_to_cpup(val), RTC_FREQ_SELECT); - - cmos_read_time(&pdev->dev, &time); - ret = rtc_valid_tm(&time); - if (ret) { - struct rtc_time def_time = { - .tm_year = 1, - .tm_mday = 1, - }; - cmos_set_time(&pdev->dev, &def_time); - } } #else static inline void cmos_of_init(struct platform_device *pdev) {} diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index cfc4141d99cd..2fc517498a5d 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c @@ -82,7 +82,7 @@ static int coh901331_read_time(struct device *dev, struct rtc_time *tm) if (readl(rtap->virtbase + COH901331_VALID)) { rtc_time_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); clk_disable(rtap->clk); - return rtc_valid_tm(tm); + return 0; } clk_disable(rtap->clk); return -EINVAL; diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 513b9bedd2c8..0abf98983e13 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h @@ -46,11 +46,3 @@ static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) return NULL; } #endif - -#ifdef CONFIG_RTC_NVMEM -void rtc_nvmem_register(struct rtc_device *rtc); -void rtc_nvmem_unregister(struct rtc_device *rtc); -#else -static inline void rtc_nvmem_register(struct rtc_device *rtc) {} -static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} -#endif diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index 3a0333e1f21a..a8856f2b9bc2 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -119,7 +119,7 @@ static int cpcap_rtc_read_time(struct device *dev, struct rtc_time *tm) cpcap2rtc_time(tm, &cpcap_tm); - return rtc_valid_tm(tm); + return 0; } static int cpcap_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c index f0ea6899c731..bf7ced095c94 100644 --- a/drivers/rtc/rtc-cros-ec.c +++ b/drivers/rtc/rtc-cros-ec.c @@ -197,10 +197,10 @@ static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) cros_ec_rtc->saved_alarm = (u32)alarm_time; } else { /* Don't set an alarm in the past. */ - if ((u32)alarm_time < current_time) - alarm_offset = EC_RTC_ALARM_CLEAR; - else - alarm_offset = (u32)alarm_time - current_time; + if ((u32)alarm_time <= current_time) + return -ETIME; + + alarm_offset = (u32)alarm_time - current_time; } ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset); diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 4273377562ec..03044e1bc497 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -187,8 +187,7 @@ static int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_min = v[0][1] & DA9052_RTC_MIN; rtc_tm->tm_sec = v[0][0] & DA9052_RTC_SEC; - ret = rtc_valid_tm(rtc_tm); - return ret; + return 0; } idx = (1-idx); diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c index 678af8648c45..e08cd8130c23 100644 --- a/drivers/rtc/rtc-da9055.c +++ b/drivers/rtc/rtc-da9055.c @@ -158,7 +158,7 @@ static int da9055_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_min = v[1] & DA9055_RTC_MIN; rtc_tm->tm_sec = v[0] & DA9055_RTC_SEC; - return rtc_valid_tm(rtc_tm); + return 0; } static int da9055_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index f85cae240f12..b4e054c64bad 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -256,7 +256,7 @@ static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) else rtc->rtc_sync = false; - return rtc_valid_tm(tm); + return 0; } static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c index 9c82b1da2d45..5f158715fb4c 100644 --- a/drivers/rtc/rtc-ds1216.c +++ b/drivers/rtc/rtc-ds1216.c @@ -99,7 +99,7 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm) if (tm->tm_year < 70) tm->tm_year += 100; - return rtc_valid_tm(tm); + return 0; } static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c index ef75c349dff9..0744916b79c5 100644 --- a/drivers/rtc/rtc-ds1286.c +++ b/drivers/rtc/rtc-ds1286.c @@ -211,7 +211,7 @@ static int ds1286_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mon--; - return rtc_valid_tm(tm); + return 0; } static int ds1286_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 0ec4be62322b..2a881150d51c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -43,7 +43,7 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time) { struct spi_device *spi = dev_get_drvdata(dev); u8 buf[1 + RTC_CLCK_LEN]; - u8 *bp = buf; + u8 *bp; int status; /* Enable writing */ @@ -98,8 +98,7 @@ static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time) time->tm_mon = bcd2bin(buf[RTC_ADDR_MON]) - 1; time->tm_year = bcd2bin(buf[RTC_ADDR_YEAR]) + 100; - /* Time may not be set */ - return rtc_valid_tm(time); + return 0; } static const struct rtc_class_ops ds1302_rtc_ops = { @@ -112,7 +111,7 @@ static int ds1302_probe(struct spi_device *spi) struct rtc_device *rtc; u8 addr; u8 buf[4]; - u8 *bp = buf; + u8 *bp; int status; /* Sanity check board setup data. This may be hooked up diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index d8df2e9e14ad..2d502fc85698 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -203,8 +203,7 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time) time->tm_hour, time->tm_mday, time->tm_mon, time->tm_year, time->tm_wday); - /* Time may not be set */ - return rtc_valid_tm(time); + return 0; } static int ds1305_set_time(struct device *dev, struct rtc_time *time) @@ -544,15 +543,6 @@ static int ds1305_nvram_write(void *priv, unsigned int off, void *buf, return spi_sync(spi, &m); } -static struct nvmem_config ds1305_nvmem_cfg = { - .name = "ds1305_nvram", - .word_size = 1, - .stride = 1, - .size = DS1305_NVRAM_LEN, - .reg_read = ds1305_nvram_read, - .reg_write = ds1305_nvram_write, -}; - /*----------------------------------------------------------------------*/ /* @@ -566,6 +556,14 @@ static int ds1305_probe(struct spi_device *spi) u8 addr, value; struct ds1305_platform_data *pdata = dev_get_platdata(&spi->dev); bool write_ctrl = false; + struct nvmem_config ds1305_nvmem_cfg = { + .name = "ds1305_nvram", + .word_size = 1, + .stride = 1, + .size = DS1305_NVRAM_LEN, + .reg_read = ds1305_nvram_read, + .reg_write = ds1305_nvram_write, + }; /* Sanity check board setup data. This may be hooked up * in 3wire mode, but we don't care. Note that unless @@ -703,15 +701,15 @@ static int ds1305_probe(struct spi_device *spi) ds1305->rtc->ops = &ds1305_ops; ds1305_nvmem_cfg.priv = ds1305; - ds1305->rtc->nvmem_config = &ds1305_nvmem_cfg; ds1305->rtc->nvram_old_abi = true; - status = rtc_register_device(ds1305->rtc); if (status) { dev_dbg(&spi->dev, "register rtc --> %d\n", status); return status; } + rtc_nvmem_register(ds1305->rtc, &ds1305_nvmem_cfg); + /* Maybe set up alarm IRQ; be ready to handle it triggering right * away. NOTE that we don't share this. The signal is active low, * and we can't ack it before a SPI message delay. We temporarily diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 923dde912f60..a13e59edff53 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -114,7 +114,6 @@ enum ds_type { # define RX8025_BIT_XST 0x20 struct ds1307 { - struct nvmem_config nvmem_cfg; enum ds_type type; unsigned long flags; #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ @@ -438,8 +437,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) t->tm_hour, t->tm_mday, t->tm_mon, t->tm_year, t->tm_wday); - /* initial clock setting can be undefined */ - return rtc_valid_tm(t); + return 0; } static int ds1307_set_time(struct device *dev, struct rtc_time *t) @@ -1696,24 +1694,26 @@ read_rtc: } } - if (chip->nvram_size) { - ds1307->nvmem_cfg.name = "ds1307_nvram"; - ds1307->nvmem_cfg.word_size = 1; - ds1307->nvmem_cfg.stride = 1; - ds1307->nvmem_cfg.size = chip->nvram_size; - ds1307->nvmem_cfg.reg_read = ds1307_nvram_read; - ds1307->nvmem_cfg.reg_write = ds1307_nvram_write; - ds1307->nvmem_cfg.priv = ds1307; - - ds1307->rtc->nvmem_config = &ds1307->nvmem_cfg; - ds1307->rtc->nvram_old_abi = true; - } - ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops; err = rtc_register_device(ds1307->rtc); if (err) return err; + if (chip->nvram_size) { + struct nvmem_config nvmem_cfg = { + .name = "ds1307_nvram", + .word_size = 1, + .stride = 1, + .size = chip->nvram_size, + .reg_read = ds1307_nvram_read, + .reg_write = ds1307_nvram_write, + .priv = ds1307, + }; + + ds1307->rtc->nvram_old_abi = true; + rtc_nvmem_register(ds1307->rtc, &nvmem_cfg); + } + ds1307_hwmon_register(ds1307); ds1307_clks_register(ds1307); diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 895fbeeb47fe..5208da4cf94a 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -153,120 +153,22 @@ static ssize_t ds1343_store_glitchfilter(struct device *dev, static DEVICE_ATTR(glitch_filter, S_IRUGO | S_IWUSR, ds1343_show_glitchfilter, ds1343_store_glitchfilter); -static ssize_t ds1343_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int ds1343_nvram_write(void *priv, unsigned int off, void *val, + size_t bytes) { - int ret; - unsigned char address; - struct device *dev = kobj_to_dev(kobj); - struct ds1343_priv *priv = dev_get_drvdata(dev); - - address = DS1343_NVRAM + off; - - ret = regmap_bulk_write(priv->map, address, buf, count); - if (ret < 0) - dev_err(&priv->spi->dev, "Error in nvram write %d", ret); + struct ds1343_priv *ds1343 = priv; - return (ret < 0) ? ret : count; + return regmap_bulk_write(ds1343->map, DS1343_NVRAM + off, val, bytes); } - -static ssize_t ds1343_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, - char *buf, loff_t off, size_t count) +static int ds1343_nvram_read(void *priv, unsigned int off, void *val, + size_t bytes) { - int ret; - unsigned char address; - struct device *dev = kobj_to_dev(kobj); - struct ds1343_priv *priv = dev_get_drvdata(dev); + struct ds1343_priv *ds1343 = priv; - address = DS1343_NVRAM + off; - - ret = regmap_bulk_read(priv->map, address, buf, count); - if (ret < 0) - dev_err(&priv->spi->dev, "Error in nvram read %d\n", ret); - - return (ret < 0) ? ret : count; + return regmap_bulk_read(ds1343->map, DS1343_NVRAM + off, val, bytes); } - -static struct bin_attribute nvram_attr = { - .attr.name = "nvram", - .attr.mode = S_IRUGO | S_IWUSR, - .read = ds1343_nvram_read, - .write = ds1343_nvram_write, - .size = DS1343_NVRAM_LEN, -}; - -static ssize_t ds1343_show_alarmstatus(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ds1343_priv *priv = dev_get_drvdata(dev); - int alarmstatus, data; - - regmap_read(priv->map, DS1343_CONTROL_REG, &data); - - alarmstatus = !!(data & DS1343_A0IE); - - if (alarmstatus) - return sprintf(buf, "enabled\n"); - else - return sprintf(buf, "disabled\n"); -} - -static DEVICE_ATTR(alarm_status, S_IRUGO, ds1343_show_alarmstatus, NULL); - -static ssize_t ds1343_show_alarmmode(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct ds1343_priv *priv = dev_get_drvdata(dev); - int alarm_mode, data; - char *alarm_str; - - regmap_read(priv->map, DS1343_ALM0_SEC_REG, &data); - alarm_mode = (data & 0x80) >> 4; - - regmap_read(priv->map, DS1343_ALM0_MIN_REG, &data); - alarm_mode |= (data & 0x80) >> 5; - - regmap_read(priv->map, DS1343_ALM0_HOUR_REG, &data); - alarm_mode |= (data & 0x80) >> 6; - - regmap_read(priv->map, DS1343_ALM0_DAY_REG, &data); - alarm_mode |= (data & 0x80) >> 7; - - switch (alarm_mode) { - case 15: - alarm_str = "each second"; - break; - - case 7: - alarm_str = "seconds match"; - break; - - case 3: - alarm_str = "minutes and seconds match"; - break; - - case 1: - alarm_str = "hours, minutes and seconds match"; - break; - - case 0: - alarm_str = "day, hours, minutes and seconds match"; - break; - - default: - alarm_str = "invalid"; - break; - } - - return sprintf(buf, "%s\n", alarm_str); -} - -static DEVICE_ATTR(alarm_mode, S_IRUGO, ds1343_show_alarmmode, NULL); - static ssize_t ds1343_show_tricklecharger(struct device *dev, struct device_attribute *attr, char *buf) { @@ -313,7 +215,6 @@ static DEVICE_ATTR(trickle_charger, S_IRUGO, ds1343_show_tricklecharger, NULL); static int ds1343_sysfs_register(struct device *dev) { - struct ds1343_priv *priv = dev_get_drvdata(dev); int err; err = device_create_file(dev, &dev_attr_glitch_filter); @@ -321,33 +222,9 @@ static int ds1343_sysfs_register(struct device *dev) return err; err = device_create_file(dev, &dev_attr_trickle_charger); - if (err) - goto error1; - - err = device_create_bin_file(dev, &nvram_attr); - if (err) - goto error2; - - if (priv->irq <= 0) - return err; - - err = device_create_file(dev, &dev_attr_alarm_mode); - if (err) - goto error3; - - err = device_create_file(dev, &dev_attr_alarm_status); if (!err) - return err; + return 0; - device_remove_file(dev, &dev_attr_alarm_mode); - -error3: - device_remove_bin_file(dev, &nvram_attr); - -error2: - device_remove_file(dev, &dev_attr_trickle_charger); - -error1: device_remove_file(dev, &dev_attr_glitch_filter); return err; @@ -355,17 +232,8 @@ error1: static void ds1343_sysfs_unregister(struct device *dev) { - struct ds1343_priv *priv = dev_get_drvdata(dev); - device_remove_file(dev, &dev_attr_glitch_filter); device_remove_file(dev, &dev_attr_trickle_charger); - device_remove_bin_file(dev, &nvram_attr); - - if (priv->irq <= 0) - return; - - device_remove_file(dev, &dev_attr_alarm_status); - device_remove_file(dev, &dev_attr_alarm_mode); } static int ds1343_read_time(struct device *dev, struct rtc_time *dt) @@ -386,7 +254,7 @@ static int ds1343_read_time(struct device *dev, struct rtc_time *dt) dt->tm_mon = bcd2bin(buf[5] & 0x1F) - 1; dt->tm_year = bcd2bin(buf[6]) + 100; /* year offset from 1900 */ - return rtc_valid_tm(dt); + return 0; } static int ds1343_set_time(struct device *dev, struct rtc_time *dt) @@ -599,14 +467,18 @@ static const struct rtc_class_ops ds1343_rtc_ops = { static int ds1343_probe(struct spi_device *spi) { struct ds1343_priv *priv; - struct regmap_config config; + struct regmap_config config = { .reg_bits = 8, .val_bits = 8, + .write_flag_mask = 0x80, }; unsigned int data; int res; - - memset(&config, 0, sizeof(config)); - config.reg_bits = 8; - config.val_bits = 8; - config.write_flag_mask = 0x80; + struct nvmem_config nvmem_cfg = { + .name = "ds1343-", + .word_size = 1, + .stride = 1, + .size = DS1343_NVRAM_LEN, + .reg_read = ds1343_nvram_read, + .reg_write = ds1343_nvram_write, + }; priv = devm_kzalloc(&spi->dev, sizeof(struct ds1343_priv), GFP_KERNEL); if (!priv) @@ -646,12 +518,19 @@ static int ds1343_probe(struct spi_device *spi) data &= ~(DS1343_OSF | DS1343_IRQF1 | DS1343_IRQF0); regmap_write(priv->map, DS1343_STATUS_REG, data); - priv->rtc = devm_rtc_device_register(&spi->dev, "ds1343", - &ds1343_rtc_ops, THIS_MODULE); - if (IS_ERR(priv->rtc)) { - dev_err(&spi->dev, "unable to register rtc ds1343\n"); + priv->rtc = devm_rtc_allocate_device(&spi->dev); + if (IS_ERR(priv->rtc)) return PTR_ERR(priv->rtc); - } + + priv->rtc->nvram_old_abi = true; + priv->rtc->ops = &ds1343_rtc_ops; + + res = rtc_register_device(priv->rtc); + if (res) + return res; + + nvmem_cfg.priv = priv; + rtc_nvmem_register(priv->rtc, &nvmem_cfg); priv->irq = spi->irq; diff --git a/drivers/rtc/rtc-ds1347.c b/drivers/rtc/rtc-ds1347.c index ccfc9d43eb1e..938512c676ee 100644 --- a/drivers/rtc/rtc-ds1347.c +++ b/drivers/rtc/rtc-ds1347.c @@ -66,7 +66,7 @@ static int ds1347_read_time(struct device *dev, struct rtc_time *dt) dt->tm_wday = bcd2bin(buf[5]) - 1; dt->tm_year = bcd2bin(buf[6]) + 100; - return rtc_valid_tm(dt); + return 0; } static int ds1347_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index 4d5b007d7fc6..3b095401f848 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -153,7 +153,7 @@ static int ds1390_read_time(struct device *dev, struct rtc_time *dt) /* adjust for century bit */ dt->tm_year = bcd2bin(chip->txrx_buf[6]) + ((chip->txrx_buf[5] & 0x80) ? 100 : 0); - return rtc_valid_tm(dt); + return 0; } static int ds1390_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 1e95312a6f2e..a7d5ca428d68 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -277,10 +277,6 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_mon--; - if (rtc_valid_tm(rtc_tm) < 0) { - dev_err(dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, rtc_tm); - } return 0; } @@ -422,20 +418,20 @@ static int ds1511_nvram_write(void *priv, unsigned int pos, void *buf, return 0; } -static struct nvmem_config ds1511_nvmem_cfg = { - .name = "ds1511_nvram", - .word_size = 1, - .stride = 1, - .size = DS1511_RAM_MAX, - .reg_read = ds1511_nvram_read, - .reg_write = ds1511_nvram_write, -}; - static int ds1511_rtc_probe(struct platform_device *pdev) { struct resource *res; struct rtc_plat_data *pdata; int ret = 0; + struct nvmem_config ds1511_nvmem_cfg = { + .name = "ds1511_nvram", + .word_size = 1, + .stride = 1, + .size = DS1511_RAM_MAX, + .reg_read = ds1511_nvram_read, + .reg_write = ds1511_nvram_write, + .priv = &pdev->dev, + }; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -478,14 +474,14 @@ static int ds1511_rtc_probe(struct platform_device *pdev) pdata->rtc->ops = &ds1511_rtc_ops; - ds1511_nvmem_cfg.priv = &pdev->dev; - pdata->rtc->nvmem_config = &ds1511_nvmem_cfg; pdata->rtc->nvram_old_abi = true; ret = rtc_register_device(pdata->rtc); if (ret) return ret; + rtc_nvmem_register(pdata->rtc, &ds1511_nvmem_cfg); + /* * if the platform has an interrupt in mind for this device, * then by all means, set it diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 9961ec646fd2..2441b9a2b366 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -127,10 +127,6 @@ static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm) /* year is 1900 + tm->tm_year */ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; - if (rtc_valid_tm(tm) < 0) { - dev_err(dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } return 0; } @@ -233,46 +229,32 @@ static const struct rtc_class_ops ds1553_rtc_ops = { .alarm_irq_enable = ds1553_rtc_alarm_irq_enable, }; -static ssize_t ds1553_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int ds1553_nvram_read(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) *buf++ = readb(ioaddr + pos++); - return count; + return 0; } -static ssize_t ds1553_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int ds1553_nvram_write(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) writeb(*buf++, ioaddr + pos++); - return count; + return 0; } -static struct bin_attribute ds1553_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - .size = RTC_OFFSET, - .read = ds1553_nvram_read, - .write = ds1553_nvram_write, -}; - static int ds1553_rtc_probe(struct platform_device *pdev) { struct resource *res; @@ -280,6 +262,15 @@ static int ds1553_rtc_probe(struct platform_device *pdev) struct rtc_plat_data *pdata; void __iomem *ioaddr; int ret = 0; + struct nvmem_config nvmem_cfg = { + .name = "ds1553_nvram", + .word_size = 1, + .stride = 1, + .size = RTC_OFFSET, + .reg_read = ds1553_nvram_read, + .reg_write = ds1553_nvram_write, + .priv = pdev, + }; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -308,11 +299,17 @@ static int ds1553_rtc_probe(struct platform_device *pdev) pdata->last_jiffies = jiffies; platform_set_drvdata(pdev, pdata); - pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &ds1553_rtc_ops, THIS_MODULE); + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(pdata->rtc)) return PTR_ERR(pdata->rtc); + pdata->rtc->ops = &ds1553_rtc_ops; + pdata->rtc->nvram_old_abi = true; + + ret = rtc_register_device(pdata->rtc); + if (ret) + return ret; + if (pdata->irq > 0) { writeb(0, ioaddr + RTC_INTERRUPTS); if (devm_request_irq(&pdev->dev, pdata->irq, @@ -323,21 +320,9 @@ static int ds1553_rtc_probe(struct platform_device *pdev) } } - ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); - if (ret) - dev_err(&pdev->dev, "unable to create sysfs file: %s\n", - ds1553_nvram_attr.attr.name); - - return 0; -} - -static int ds1553_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + if (rtc_nvmem_register(pdata->rtc, &nvmem_cfg)) + dev_err(&pdev->dev, "unable to register nvmem\n"); - sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); - if (pdata->irq > 0) - writeb(0, pdata->ioaddr + RTC_INTERRUPTS); return 0; } @@ -346,7 +331,6 @@ MODULE_ALIAS("platform:rtc-ds1553"); static struct platform_driver ds1553_rtc_driver = { .probe = ds1553_rtc_probe, - .remove = ds1553_rtc_remove, .driver = { .name = "rtc-ds1553", }, diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index ed43b4311660..1a39829d2b40 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c @@ -306,7 +306,7 @@ ds1685_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_isdst = 0; /* RTC has hardcoded timezone, so don't use. */ - return rtc_valid_tm(tm); + return 0; } /** diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 3abf1cbfb8ce..2d781180e968 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -53,9 +53,7 @@ struct rtc_plat_data { void __iomem *ioaddr_nvram; void __iomem *ioaddr_rtc; - size_t size_nvram; unsigned long last_jiffies; - struct bin_attribute nvram_attr; }; static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -114,7 +112,7 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm) /* year is 1900 + tm->tm_year */ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; - return rtc_valid_tm(tm); + return 0; } static const struct rtc_class_ops ds1742_rtc_ops = { @@ -122,34 +120,28 @@ static const struct rtc_class_ops ds1742_rtc_ops = { .set_time = ds1742_rtc_set_time, }; -static ssize_t ds1742_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int ds1742_nvram_read(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + struct rtc_plat_data *pdata = priv; void __iomem *ioaddr = pdata->ioaddr_nvram; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) *buf++ = readb(ioaddr + pos++); - return count; + return 0; } -static ssize_t ds1742_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int ds1742_nvram_write(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + struct rtc_plat_data *pdata = priv; void __iomem *ioaddr = pdata->ioaddr_nvram; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) writeb(*buf++, ioaddr + pos++); - return count; + return 0; } static int ds1742_rtc_probe(struct platform_device *pdev) @@ -160,6 +152,14 @@ static int ds1742_rtc_probe(struct platform_device *pdev) struct rtc_plat_data *pdata; void __iomem *ioaddr; int ret = 0; + struct nvmem_config nvmem_cfg = { + .name = "ds1742_nvram", + .word_size = 1, + .stride = 1, + .reg_read = ds1742_nvram_read, + .reg_write = ds1742_nvram_write, + }; + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -171,15 +171,10 @@ static int ds1742_rtc_probe(struct platform_device *pdev) return PTR_ERR(ioaddr); pdata->ioaddr_nvram = ioaddr; - pdata->size_nvram = resource_size(res) - RTC_SIZE; - pdata->ioaddr_rtc = ioaddr + pdata->size_nvram; + pdata->ioaddr_rtc = ioaddr + resource_size(res) - RTC_SIZE; - sysfs_bin_attr_init(&pdata->nvram_attr); - pdata->nvram_attr.attr.name = "nvram"; - pdata->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; - pdata->nvram_attr.read = ds1742_nvram_read; - pdata->nvram_attr.write = ds1742_nvram_write; - pdata->nvram_attr.size = pdata->size_nvram; + nvmem_cfg.size = resource_size(res) - RTC_SIZE; + nvmem_cfg.priv = pdata; /* turn RTC on if it was not on */ ioaddr = pdata->ioaddr_rtc; @@ -196,24 +191,21 @@ static int ds1742_rtc_probe(struct platform_device *pdev) pdata->last_jiffies = jiffies; platform_set_drvdata(pdev, pdata); - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &ds1742_rtc_ops, THIS_MODULE); + + rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); - ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); - if (ret) - dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", - pdata->nvram_attr.attr.name); + rtc->ops = &ds1742_rtc_ops; + rtc->nvram_old_abi = true; - return 0; -} + ret = rtc_register_device(rtc); + if (ret) + return ret; -static int ds1742_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + if (rtc_nvmem_register(rtc, &nvmem_cfg)) + dev_err(&pdev->dev, "Unable to register nvmem\n"); - sysfs_remove_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); return 0; } @@ -225,7 +217,6 @@ MODULE_DEVICE_TABLE(of, ds1742_rtc_of_match); static struct platform_driver ds1742_rtc_driver = { .probe = ds1742_rtc_probe, - .remove = ds1742_rtc_remove, .driver = { .name = "rtc-ds1742", .of_match_table = of_match_ptr(ds1742_rtc_of_match), diff --git a/drivers/rtc/rtc-ds2404.c b/drivers/rtc/rtc-ds2404.c index 9a1582ed7070..b886b6a5c178 100644 --- a/drivers/rtc/rtc-ds2404.c +++ b/drivers/rtc/rtc-ds2404.c @@ -207,7 +207,7 @@ static int ds2404_read_time(struct device *dev, struct rtc_time *dt) time = le32_to_cpu(time); rtc_time_to_tm(time, dt); - return rtc_valid_tm(dt); + return 0; } static int ds2404_set_mmss(struct device *dev, unsigned long secs) diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index 0550f7ba464f..7184e5145f12 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -145,7 +145,7 @@ static int ds3232_read_time(struct device *dev, struct rtc_time *time) time->tm_year = bcd2bin(year) + add_century; - return rtc_valid_tm(time); + return 0; } static int ds3232_set_time(struct device *dev, struct rtc_time *time) diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c index 0130afd7fe88..3454e7814524 100644 --- a/drivers/rtc/rtc-efi.c +++ b/drivers/rtc/rtc-efi.c @@ -176,7 +176,7 @@ static int efi_read_time(struct device *dev, struct rtc_time *tm) if (!convert_from_efi_time(&eft, tm)) return -EIO; - return rtc_valid_tm(tm); + return 0; } static int efi_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c index 576eadbba296..e1137670d4d2 100644 --- a/drivers/rtc/rtc-fm3130.c +++ b/drivers/rtc/rtc-fm3130.c @@ -136,8 +136,7 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t) t->tm_hour, t->tm_mday, t->tm_mon, t->tm_year, t->tm_wday); - /* initial clock setting can be undefined */ - return rtc_valid_tm(t); + return 0; } diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c index d67769265185..a1c44d0c8557 100644 --- a/drivers/rtc/rtc-goldfish.c +++ b/drivers/rtc/rtc-goldfish.c @@ -235,3 +235,5 @@ static struct platform_driver goldfish_rtc = { }; module_platform_driver(goldfish_rtc); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 38586a024ee8..890ccfc9e5aa 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -104,8 +104,9 @@ static int isl12022_write_reg(struct i2c_client *client, * In the routines that deal directly with the isl12022 hardware, we use * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. */ -static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm) +static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); uint8_t buf[ISL12022_REG_INT + 1]; int ret; @@ -149,11 +150,12 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } -static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) +static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct isl12022 *isl12022 = i2c_get_clientdata(client); size_t i; int ret; @@ -199,7 +201,7 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) return ret; } - isl12022->write_enabled = 1; + isl12022->write_enabled = true; } /* hours, minutes and seconds */ @@ -228,16 +230,6 @@ static int isl12022_set_datetime(struct i2c_client *client, struct rtc_time *tm) return 0; } -static int isl12022_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return isl12022_get_datetime(to_i2c_client(dev), tm); -} - -static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return isl12022_set_datetime(to_i2c_client(dev), tm); -} - static const struct rtc_class_ops isl12022_rtc_ops = { .read_time = isl12022_rtc_read_time, .set_time = isl12022_rtc_set_time, diff --git a/drivers/rtc/rtc-isl12026.c b/drivers/rtc/rtc-isl12026.c new file mode 100644 index 000000000000..97f594f9667c --- /dev/null +++ b/drivers/rtc/rtc-isl12026.c @@ -0,0 +1,501 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * An I2C driver for the Intersil ISL 12026 + * + * Copyright (c) 2018 Cavium, Inc. + */ +#include <linux/bcd.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/nvmem-provider.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/rtc.h> +#include <linux/slab.h> + +/* register offsets */ +#define ISL12026_REG_PWR 0x14 +# define ISL12026_REG_PWR_BSW BIT(6) +# define ISL12026_REG_PWR_SBIB BIT(7) +#define ISL12026_REG_SC 0x30 +#define ISL12026_REG_HR 0x32 +# define ISL12026_REG_HR_MIL BIT(7) /* military or 24 hour time */ +#define ISL12026_REG_SR 0x3f +# define ISL12026_REG_SR_RTCF BIT(0) +# define ISL12026_REG_SR_WEL BIT(1) +# define ISL12026_REG_SR_RWEL BIT(2) +# define ISL12026_REG_SR_MBZ BIT(3) +# define ISL12026_REG_SR_OSCF BIT(4) + +/* The EEPROM array responds at i2c address 0x57 */ +#define ISL12026_EEPROM_ADDR 0x57 + +#define ISL12026_PAGESIZE 16 +#define ISL12026_NVMEM_WRITE_TIME 20 + +struct isl12026 { + struct rtc_device *rtc; + struct i2c_client *nvm_client; +}; + +static int isl12026_read_reg(struct i2c_client *client, int reg) +{ + u8 addr[] = {0, reg}; + u8 val; + int ret; + + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = sizeof(addr), + .buf = addr + }, { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = &val + } + }; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "read reg error, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + } else { + ret = val; + } + + return ret; +} + +static int isl12026_arm_write(struct i2c_client *client) +{ + int ret; + u8 op[3]; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = op + }; + + /* Set SR.WEL */ + op[0] = 0; + op[1] = ISL12026_REG_SR; + op[2] = ISL12026_REG_SR_WEL; + msg.len = 3; + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret != 1) { + dev_err(&client->dev, "write error SR.WEL, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } + + /* Set SR.WEL and SR.RWEL */ + op[2] = ISL12026_REG_SR_WEL | ISL12026_REG_SR_RWEL; + msg.len = 3; + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret != 1) { + dev_err(&client->dev, + "write error SR.WEL|SR.RWEL, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } else { + ret = 0; + } +out: + return ret; +} + +static int isl12026_disarm_write(struct i2c_client *client) +{ + int ret; + u8 op[3] = {0, ISL12026_REG_SR, 0}; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = sizeof(op), + .buf = op + }; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret != 1) { + dev_err(&client->dev, + "write error SR, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + } else { + ret = 0; + } + + return ret; +} + +static int isl12026_write_reg(struct i2c_client *client, int reg, u8 val) +{ + int ret; + u8 op[3] = {0, reg, val}; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = sizeof(op), + .buf = op + }; + + ret = isl12026_arm_write(client); + if (ret) + return ret; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret != 1) { + dev_err(&client->dev, "write error CCR, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } + + msleep(ISL12026_NVMEM_WRITE_TIME); + + ret = isl12026_disarm_write(client); +out: + return ret; +} + +static int isl12026_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + int ret; + u8 op[10]; + struct i2c_msg msg = { + .addr = client->addr, + .flags = 0, + .len = sizeof(op), + .buf = op + }; + + ret = isl12026_arm_write(client); + if (ret) + return ret; + + /* Set the CCR registers */ + op[0] = 0; + op[1] = ISL12026_REG_SC; + op[2] = bin2bcd(tm->tm_sec); /* SC */ + op[3] = bin2bcd(tm->tm_min); /* MN */ + op[4] = bin2bcd(tm->tm_hour) | ISL12026_REG_HR_MIL; /* HR */ + op[5] = bin2bcd(tm->tm_mday); /* DT */ + op[6] = bin2bcd(tm->tm_mon + 1); /* MO */ + op[7] = bin2bcd(tm->tm_year % 100); /* YR */ + op[8] = bin2bcd(tm->tm_wday & 7); /* DW */ + op[9] = bin2bcd(tm->tm_year >= 100 ? 20 : 19); /* Y2K */ + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret != 1) { + dev_err(&client->dev, "write error CCR, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } + + ret = isl12026_disarm_write(client); +out: + return ret; +} + +static int isl12026_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct i2c_client *client = to_i2c_client(dev); + u8 ccr[8]; + u8 addr[2]; + u8 sr; + int ret; + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = sizeof(addr), + .buf = addr + }, { + .addr = client->addr, + .flags = I2C_M_RD, + } + }; + + /* First, read SR */ + addr[0] = 0; + addr[1] = ISL12026_REG_SR; + msgs[1].len = 1; + msgs[1].buf = &sr; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "read error, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } + + if (sr & ISL12026_REG_SR_RTCF) + dev_warn(&client->dev, "Real-Time Clock Failure on read\n"); + if (sr & ISL12026_REG_SR_OSCF) + dev_warn(&client->dev, "Oscillator Failure on read\n"); + + /* Second, CCR regs */ + addr[0] = 0; + addr[1] = ISL12026_REG_SC; + msgs[1].len = sizeof(ccr); + msgs[1].buf = ccr; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) { + dev_err(&client->dev, "read error, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + goto out; + } + + tm->tm_sec = bcd2bin(ccr[0] & 0x7F); + tm->tm_min = bcd2bin(ccr[1] & 0x7F); + if (ccr[2] & ISL12026_REG_HR_MIL) + tm->tm_hour = bcd2bin(ccr[2] & 0x3F); + else + tm->tm_hour = bcd2bin(ccr[2] & 0x1F) + + ((ccr[2] & 0x20) ? 12 : 0); + tm->tm_mday = bcd2bin(ccr[3] & 0x3F); + tm->tm_mon = bcd2bin(ccr[4] & 0x1F) - 1; + tm->tm_year = bcd2bin(ccr[5]); + if (bcd2bin(ccr[7]) == 20) + tm->tm_year += 100; + tm->tm_wday = ccr[6] & 0x07; + + ret = 0; +out: + return ret; +} + +static const struct rtc_class_ops isl12026_rtc_ops = { + .read_time = isl12026_rtc_read_time, + .set_time = isl12026_rtc_set_time, +}; + +static int isl12026_nvm_read(void *p, unsigned int offset, + void *val, size_t bytes) +{ + struct isl12026 *priv = p; + int ret; + u8 addr[2]; + struct i2c_msg msgs[] = { + { + .addr = priv->nvm_client->addr, + .flags = 0, + .len = sizeof(addr), + .buf = addr + }, { + .addr = priv->nvm_client->addr, + .flags = I2C_M_RD, + .buf = val + } + }; + + /* + * offset and bytes checked and limited by nvmem core, so + * proceed without further checks. + */ + ret = mutex_lock_interruptible(&priv->rtc->ops_lock); + if (ret) + return ret; + + /* 2 bytes of address, most significant first */ + addr[0] = offset >> 8; + addr[1] = offset; + msgs[1].len = bytes; + ret = i2c_transfer(priv->nvm_client->adapter, msgs, ARRAY_SIZE(msgs)); + + mutex_unlock(&priv->rtc->ops_lock); + + if (ret != ARRAY_SIZE(msgs)) { + dev_err(&priv->nvm_client->dev, + "nvmem read error, ret=%d\n", ret); + return ret < 0 ? ret : -EIO; + } + + return 0; +} + +static int isl12026_nvm_write(void *p, unsigned int offset, + void *val, size_t bytes) +{ + struct isl12026 *priv = p; + int ret; + u8 *v = val; + size_t chunk_size, num_written; + u8 payload[ISL12026_PAGESIZE + 2]; /* page + 2 address bytes */ + struct i2c_msg msgs[] = { + { + .addr = priv->nvm_client->addr, + .flags = 0, + .buf = payload + } + }; + + /* + * offset and bytes checked and limited by nvmem core, so + * proceed without further checks. + */ + ret = mutex_lock_interruptible(&priv->rtc->ops_lock); + if (ret) + return ret; + + num_written = 0; + while (bytes) { + chunk_size = round_down(offset, ISL12026_PAGESIZE) + + ISL12026_PAGESIZE - offset; + chunk_size = min(bytes, chunk_size); + /* + * 2 bytes of address, most significant first, followed + * by page data bytes + */ + memcpy(payload + 2, v + num_written, chunk_size); + payload[0] = offset >> 8; + payload[1] = offset; + msgs[0].len = chunk_size + 2; + ret = i2c_transfer(priv->nvm_client->adapter, + msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) { + dev_err(&priv->nvm_client->dev, + "nvmem write error, ret=%d\n", ret); + ret = ret < 0 ? ret : -EIO; + break; + } + ret = 0; + bytes -= chunk_size; + offset += chunk_size; + num_written += chunk_size; + msleep(ISL12026_NVMEM_WRITE_TIME); + } + + mutex_unlock(&priv->rtc->ops_lock); + + return ret; +} + +static void isl12026_force_power_modes(struct i2c_client *client) +{ + int ret; + int pwr, requested_pwr; + u32 bsw_val, sbib_val; + bool set_bsw, set_sbib; + + /* + * If we can read the of_property, set the specified value. + * If there is an error reading the of_property (likely + * because it does not exist), keep the current value. + */ + ret = of_property_read_u32(client->dev.of_node, + "isil,pwr-bsw", &bsw_val); + set_bsw = (ret == 0); + + ret = of_property_read_u32(client->dev.of_node, + "isil,pwr-sbib", &sbib_val); + set_sbib = (ret == 0); + + /* Check if PWR.BSW and/or PWR.SBIB need specified values */ + if (!set_bsw && !set_sbib) + return; + + pwr = isl12026_read_reg(client, ISL12026_REG_PWR); + if (pwr < 0) { + dev_warn(&client->dev, "Error: Failed to read PWR %d\n", pwr); + return; + } + + requested_pwr = pwr; + + if (set_bsw) { + if (bsw_val) + requested_pwr |= ISL12026_REG_PWR_BSW; + else + requested_pwr &= ~ISL12026_REG_PWR_BSW; + } /* else keep current BSW */ + + if (set_sbib) { + if (sbib_val) + requested_pwr |= ISL12026_REG_PWR_SBIB; + else + requested_pwr &= ~ISL12026_REG_PWR_SBIB; + } /* else keep current SBIB */ + + if (pwr >= 0 && pwr != requested_pwr) { + dev_dbg(&client->dev, "PWR: %02x\n", pwr); + dev_dbg(&client->dev, "Updating PWR to: %02x\n", requested_pwr); + isl12026_write_reg(client, ISL12026_REG_PWR, requested_pwr); + } +} + +static int isl12026_probe_new(struct i2c_client *client) +{ + struct isl12026 *priv; + int ret; + struct nvmem_config nvm_cfg = { + .name = "isl12026-", + .base_dev = &client->dev, + .stride = 1, + .word_size = 1, + .size = 512, + .reg_read = isl12026_nvm_read, + .reg_write = isl12026_nvm_write, + }; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -ENODEV; + + priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + i2c_set_clientdata(client, priv); + + isl12026_force_power_modes(client); + + priv->nvm_client = i2c_new_dummy(client->adapter, ISL12026_EEPROM_ADDR); + if (!priv->nvm_client) + return -ENOMEM; + + priv->rtc = devm_rtc_allocate_device(&client->dev); + ret = PTR_ERR_OR_ZERO(priv->rtc); + if (ret) + return ret; + + priv->rtc->ops = &isl12026_rtc_ops; + nvm_cfg.priv = priv; + ret = rtc_nvmem_register(priv->rtc, &nvm_cfg); + if (ret) + return ret; + + return rtc_register_device(priv->rtc); +} + +static int isl12026_remove(struct i2c_client *client) +{ + struct isl12026 *priv = i2c_get_clientdata(client); + + i2c_unregister_device(priv->nvm_client); + return 0; +} + +static const struct of_device_id isl12026_dt_match[] = { + { .compatible = "isil,isl12026" }, + { } +}; +MODULE_DEVICE_TABLE(of, isl12026_dt_match); + +static struct i2c_driver isl12026_driver = { + .driver = { + .name = "rtc-isl12026", + .of_match_table = isl12026_dt_match, + }, + .probe_new = isl12026_probe_new, + .remove = isl12026_remove, +}; + +module_i2c_driver(isl12026_driver); + +MODULE_DESCRIPTION("ISL 12026 RTC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 8dd299c6a1f3..1a2c38cc0178 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c @@ -459,6 +459,11 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) } /* clear WRTC again */ + sr = isl1208_i2c_get_sr(client); + if (sr < 0) { + dev_err(&client->dev, "%s: reading SR failed\n", __func__); + return sr; + } sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); if (sr < 0) { @@ -630,29 +635,12 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (isl1208_i2c_validate_client(client) < 0) return -ENODEV; - if (client->irq > 0) { - rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, - isl1208_rtc_interrupt, - IRQF_SHARED | IRQF_ONESHOT, - isl1208_driver.driver.name, - client); - if (!rc) { - device_init_wakeup(&client->dev, 1); - enable_irq_wake(client->irq); - } else { - dev_err(&client->dev, - "Unable to request irq %d, no alarm support\n", - client->irq); - client->irq = 0; - } - } - - rtc = devm_rtc_device_register(&client->dev, isl1208_driver.driver.name, - &isl1208_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_allocate_device(&client->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + rtc->ops = &isl1208_rtc_ops; + i2c_set_clientdata(client, rtc); rc = isl1208_i2c_get_sr(client); @@ -669,7 +657,24 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) if (rc) return rc; - return 0; + if (client->irq > 0) { + rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, + isl1208_rtc_interrupt, + IRQF_SHARED | IRQF_ONESHOT, + isl1208_driver.driver.name, + client); + if (!rc) { + device_init_wakeup(&client->dev, 1); + enable_irq_wake(client->irq); + } else { + dev_err(&client->dev, + "Unable to request irq %d, no alarm support\n", + client->irq); + client->irq = 0; + } + } + + return rtc_register_device(rtc); } static int diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index ff65a7d2b9c9..d0a891777f44 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -173,7 +173,7 @@ static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time) rtc_time_to_tm(secs, time); - return rtc_valid_tm(time); + return 0; } static int jz4740_rtc_set_mmss(struct device *dev, unsigned long secs) diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 1ae7da5cfc60..4a3c0f3aab14 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -52,13 +52,11 @@ EXPORT_SYMBOL(rtc_year_days); */ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) { - unsigned int month, year; - unsigned long secs; + unsigned int month, year, secs; int days; /* time must be positive */ - days = div_s64(time, 86400); - secs = time - (unsigned int) days * 86400; + days = div_s64_rem(time, 86400, &secs); /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; @@ -67,7 +65,7 @@ void rtc_time64_to_tm(time64_t time, struct rtc_time *tm) days -= (year - 1970) * 365 + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(1970 - 1); - if (days < 0) { + while (days < 0) { year -= 1; days += 365 + is_leap_year(year); } diff --git a/drivers/rtc/rtc-lpc24xx.c b/drivers/rtc/rtc-lpc24xx.c index 59d99596fdeb..14dc7b04fae0 100644 --- a/drivers/rtc/rtc-lpc24xx.c +++ b/drivers/rtc/rtc-lpc24xx.c @@ -110,7 +110,7 @@ static int lpc24xx_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_year = CT1_YEAR(ct1); tm->tm_yday = CT2_DOY(ct2); - return rtc_valid_tm(tm); + return 0; } static int lpc24xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) diff --git a/drivers/rtc/rtc-lpc32xx.c b/drivers/rtc/rtc-lpc32xx.c index 887871c3d526..3ba87239aacc 100644 --- a/drivers/rtc/rtc-lpc32xx.c +++ b/drivers/rtc/rtc-lpc32xx.c @@ -70,7 +70,7 @@ static int lpc32xx_rtc_read_time(struct device *dev, struct rtc_time *time) elapsed_sec = rtc_readl(rtc, LPC32XX_RTC_UCOUNT); rtc_time_to_tm(elapsed_sec, time); - return rtc_valid_tm(time); + return 0; } static int lpc32xx_rtc_set_mmss(struct device *dev, unsigned long secs) diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c index e04ca54f21e2..045af1135e48 100644 --- a/drivers/rtc/rtc-ls1x.c +++ b/drivers/rtc/rtc-ls1x.c @@ -98,7 +98,7 @@ static int ls1x_rtc_read_time(struct device *dev, struct rtc_time *rtm) ls1x_get_min(v), ls1x_get_sec(v)); rtc_time_to_tm(t, rtm); - return rtc_valid_tm(rtm); + return 0; } static int ls1x_rtc_set_time(struct device *dev, struct rtc_time *rtm) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index c90fba3ed861..ad03e2f12f5d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -73,7 +73,6 @@ #define M41T80_FEATURE_WD BIT(3) /* Extra watchdog resolution */ #define M41T80_FEATURE_SQ_ALT BIT(4) /* RSx bits are in reg 4 */ -static DEFINE_MUTEX(m41t80_rtc_mutex); static const struct i2c_device_id m41t80_id[] = { { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT }, { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD }, @@ -199,9 +198,9 @@ static irqreturn_t m41t80_handle_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int m41t80_get_datetime(struct i2c_client *client, - struct rtc_time *tm) +static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); unsigned char buf[8]; int err, flags; @@ -230,12 +229,12 @@ static int m41t80_get_datetime(struct i2c_client *client, /* assume 20YY not 19YY, and ignore the Century Bit */ tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100; - return rtc_valid_tm(tm); + return 0; } -/* Sets the given date and time to the real time clock. */ -static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm) +static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct m41t80_data *clientdata = i2c_get_clientdata(client); unsigned char buf[8]; int err, flags; @@ -298,16 +297,6 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq) return 0; } -static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return m41t80_get_datetime(to_i2c_client(dev), tm); -} - -static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return m41t80_set_datetime(to_i2c_client(dev), tm); -} - static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct i2c_client *client = to_i2c_client(dev); @@ -598,6 +587,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80) * ***************************************************************************** */ +static DEFINE_MUTEX(m41t80_rtc_mutex); static struct i2c_client *save_client; /* Default margin */ @@ -885,7 +875,6 @@ static int m41t80_probe(struct i2c_client *client, { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); int rc = 0; - struct rtc_device *rtc = NULL; struct rtc_time tm; struct m41t80_data *m41t80_data = NULL; bool wakeup_source = false; @@ -909,6 +898,10 @@ static int m41t80_probe(struct i2c_client *client, m41t80_data->features = id->driver_data; i2c_set_clientdata(client, m41t80_data); + m41t80_data->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(m41t80_data->rtc)) + return PTR_ERR(m41t80_data->rtc); + #ifdef CONFIG_OF wakeup_source = of_property_read_bool(client->dev.of_node, "wakeup-source"); @@ -932,15 +925,11 @@ static int m41t80_probe(struct i2c_client *client, device_init_wakeup(&client->dev, true); } - rtc = devm_rtc_device_register(&client->dev, client->name, - &m41t80_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + m41t80_data->rtc->ops = &m41t80_rtc_ops; - m41t80_data->rtc = rtc; if (client->irq <= 0) { /* We cannot support UIE mode if we do not have an IRQ line */ - rtc->uie_unsupported = 1; + m41t80_data->rtc->uie_unsupported = 1; } /* Make sure HT (Halt Update) bit is cleared */ @@ -948,7 +937,7 @@ static int m41t80_probe(struct i2c_client *client, if (rc >= 0 && rc & M41T80_ALHOUR_HT) { if (m41t80_data->features & M41T80_FEATURE_HT) { - m41t80_get_datetime(client, &tm); + m41t80_rtc_read_time(&client->dev, &tm); dev_info(&client->dev, "HT bit was set!\n"); dev_info(&client->dev, "Power Down at %04i-%02i-%02i %02i:%02i:%02i\n", @@ -993,6 +982,11 @@ static int m41t80_probe(struct i2c_client *client, if (m41t80_data->features & M41T80_FEATURE_SQ) m41t80_sqw_register_clk(m41t80_data); #endif + + rc = rtc_register_device(m41t80_data->rtc); + if (rc) + return rc; + return 0; } diff --git a/drivers/rtc/rtc-m41t93.c b/drivers/rtc/rtc-m41t93.c index 5ac45fc1a787..4a08a9dabc82 100644 --- a/drivers/rtc/rtc-m41t93.c +++ b/drivers/rtc/rtc-m41t93.c @@ -159,7 +159,7 @@ static int m41t93_get_time(struct device *dev, struct rtc_time *tm) tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - return ret < 0 ? ret : rtc_valid_tm(tm); + return ret; } diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c index 1f0eb79e69f9..bab82b4be356 100644 --- a/drivers/rtc/rtc-m41t94.c +++ b/drivers/rtc/rtc-m41t94.c @@ -99,8 +99,7 @@ static int m41t94_read_time(struct device *dev, struct rtc_time *tm) tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - /* initial clock setting can be undefined */ - return rtc_valid_tm(tm); + return 0; } static const struct rtc_class_ops m41t94_rtc_ops = { diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index 810f4ea481e4..0cf6507de3c7 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -84,7 +84,7 @@ static int m48t35_read_time(struct device *dev, struct rtc_time *tm) tm->tm_year += 100; tm->tm_mon--; - return rtc_valid_tm(tm); + return 0; } static int m48t35_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index d99a705bec07..216fac62c888 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -105,7 +105,7 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_dbg(dev, "RTC read time %04d-%02d-%02d %02d/%02d/%02d\n", tm->tm_year + 1900, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - return rtc_valid_tm(tm); + return 0; } static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -334,16 +334,16 @@ static const struct rtc_class_ops m48t02_rtc_ops = { .set_time = m48t59_rtc_set_time, }; -static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int m48t59_nvram_read(void *priv, unsigned int offset, void *val, + size_t size) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; + struct device *dev = &pdev->dev; struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = platform_get_drvdata(pdev); ssize_t cnt = 0; unsigned long flags; + u8 *buf = val; spin_lock_irqsave(&m48t59->lock, flags); @@ -352,19 +352,19 @@ static ssize_t m48t59_nvram_read(struct file *filp, struct kobject *kobj, spin_unlock_irqrestore(&m48t59->lock, flags); - return cnt; + return 0; } -static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int m48t59_nvram_write(void *priv, unsigned int offset, void *val, + size_t size) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); + struct platform_device *pdev = priv; + struct device *dev = &pdev->dev; struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); struct m48t59_private *m48t59 = platform_get_drvdata(pdev); ssize_t cnt = 0; unsigned long flags; + u8 *buf = val; spin_lock_irqsave(&m48t59->lock, flags); @@ -373,18 +373,9 @@ static ssize_t m48t59_nvram_write(struct file *filp, struct kobject *kobj, spin_unlock_irqrestore(&m48t59->lock, flags); - return cnt; + return 0; } -static struct bin_attribute m48t59_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - .read = m48t59_nvram_read, - .write = m48t59_nvram_write, -}; - static int m48t59_rtc_probe(struct platform_device *pdev) { struct m48t59_plat_data *pdata = dev_get_platdata(&pdev->dev); @@ -393,6 +384,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev) int ret = -ENOMEM; char *name; const struct rtc_class_ops *ops; + struct nvmem_config nvmem_cfg = { + .name = "m48t59-", + .word_size = 1, + .stride = 1, + .reg_read = m48t59_nvram_read, + .reg_write = m48t59_nvram_write, + .priv = pdev, + }; /* This chip could be memory-mapped or I/O-mapped */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -480,23 +479,22 @@ static int m48t59_rtc_probe(struct platform_device *pdev) spin_lock_init(&m48t59->lock); platform_set_drvdata(pdev, m48t59); - m48t59->rtc = devm_rtc_device_register(&pdev->dev, name, ops, - THIS_MODULE); + m48t59->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(m48t59->rtc)) return PTR_ERR(m48t59->rtc); - m48t59_nvram_attr.size = pdata->offset; + m48t59->rtc->nvram_old_abi = true; + m48t59->rtc->ops = ops; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); + nvmem_cfg.size = pdata->offset; + ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg); if (ret) return ret; - return 0; -} + ret = rtc_register_device(m48t59->rtc); + if (ret) + return ret; -static int m48t59_rtc_remove(struct platform_device *pdev) -{ - sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); return 0; } @@ -508,7 +506,6 @@ static struct platform_driver m48t59_rtc_driver = { .name = "rtc-m48t59", }, .probe = m48t59_rtc_probe, - .remove = m48t59_rtc_remove, }; module_platform_driver(m48t59_rtc_driver); diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index d9aea9b6d9cd..a9533535c3b7 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -100,7 +100,7 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) if (m48t86_readb(dev, M48T86_HOUR) & 0x80) tm->tm_hour += 12; - return rtc_valid_tm(tm); + return 0; } static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -218,21 +218,21 @@ static bool m48t86_verify_chip(struct platform_device *pdev) return false; } -static struct nvmem_config m48t86_nvmem_cfg = { - .name = "m48t86_nvram", - .word_size = 1, - .stride = 1, - .size = M48T86_NVRAM_LEN, - .reg_read = m48t86_nvram_read, - .reg_write = m48t86_nvram_write, -}; - static int m48t86_rtc_probe(struct platform_device *pdev) { struct m48t86_rtc_info *info; struct resource *res; unsigned char reg; int err; + struct nvmem_config m48t86_nvmem_cfg = { + .name = "m48t86_nvram", + .word_size = 1, + .stride = 1, + .size = M48T86_NVRAM_LEN, + .reg_read = m48t86_nvram_read, + .reg_write = m48t86_nvram_write, + .priv = &pdev->dev, + }; info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); if (!info) @@ -264,15 +264,14 @@ static int m48t86_rtc_probe(struct platform_device *pdev) return PTR_ERR(info->rtc); info->rtc->ops = &m48t86_rtc_ops; - - m48t86_nvmem_cfg.priv = &pdev->dev; - info->rtc->nvmem_config = &m48t86_nvmem_cfg; info->rtc->nvram_old_abi = true; err = rtc_register_device(info->rtc); if (err) return err; + rtc_nvmem_register(info->rtc, &m48t86_nvmem_cfg); + /* read battery status */ reg = m48t86_readb(&pdev->dev, M48T86_D); dev_info(&pdev->dev, "battery %s\n", diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index cbdc86a560ba..ab60f13fa3ef 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -139,8 +139,9 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) return -EIO; } -static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) +static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); int rc; u8 regs[MAX6900_REG_LEN]; @@ -157,7 +158,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) bcd2bin(regs[MAX6900_REG_CENTURY]) * 100 - 1900; tm->tm_wday = bcd2bin(regs[MAX6900_REG_DW]); - return rtc_valid_tm(tm); + return 0; } static int max6900_i2c_clear_write_protect(struct i2c_client *client) @@ -165,9 +166,9 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client) return i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0); } -static int -max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) +static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); u8 regs[MAX6900_REG_LEN]; int rc; @@ -193,16 +194,6 @@ max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm) return 0; } -static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return max6900_i2c_read_time(to_i2c_client(dev), tm); -} - -static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return max6900_i2c_set_time(to_i2c_client(dev), tm); -} - static const struct rtc_class_ops max6900_rtc_ops = { .read_time = max6900_rtc_read_time, .set_time = max6900_rtc_set_time, diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 315d09e0f2c1..745827463367 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -85,7 +85,7 @@ static int max6902_read_time(struct device *dev, struct rtc_time *dt) dt->tm_year += century; dt->tm_year -= 1900; - return rtc_valid_tm(dt); + return 0; } static int max6902_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-max6916.c b/drivers/rtc/rtc-max6916.c index 623ab27b2757..7e908a490cf6 100644 --- a/drivers/rtc/rtc-max6916.c +++ b/drivers/rtc/rtc-max6916.c @@ -75,7 +75,7 @@ static int max6916_read_time(struct device *dev, struct rtc_time *dt) dt->tm_wday = bcd2bin(buf[5]) - 1; dt->tm_year = bcd2bin(buf[6]) + 100; - return rtc_valid_tm(dt); + return 0; } static int max6916_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 182fdd00e290..cefde273fae6 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -364,11 +364,9 @@ static int max77686_rtc_read_time(struct device *dev, struct rtc_time *tm) max77686_rtc_data_to_tm(data, tm, info); - ret = rtc_valid_tm(tm); - out: mutex_unlock(&info->lock); - return ret; + return 0; } static int max77686_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index db984d4bf952..e8cee123e8aa 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c @@ -153,7 +153,7 @@ static int max8997_rtc_read_time(struct device *dev, struct rtc_time *tm) max8997_rtc_data_to_tm(data, tm, info->rtc_24hr_mode); - return rtc_valid_tm(tm); + return 0; } static int max8997_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index 30804b00985e..d8c0f9b3f87d 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -120,7 +120,7 @@ static int max8998_rtc_read_time(struct device *dev, struct rtc_time *tm) max8998_data_to_tm(data, tm); - return rtc_valid_tm(tm); + return 0; } static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index 30b8ef6a3676..1f892b238ddb 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c @@ -85,7 +85,7 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time64_to_tm((time64_t)days1 * SEC_PER_DAY + seconds, tm); - return rtc_valid_tm(tm); + return 0; } static int mc13xxx_rtc_set_mmss(struct device *dev, time64_t secs) diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c index 77f21331ae21..00e11c1b2186 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c @@ -82,7 +82,7 @@ static int mcp795_rtcc_write(struct device *dev, u8 addr, u8 *data, u8 count) { struct spi_device *spi = to_spi_device(dev); int ret; - u8 tx[2 + count]; + u8 tx[257]; tx[0] = MCP795_WRITE; tx[1] = addr; @@ -262,7 +262,7 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim) tim->tm_year + 1900, tim->tm_mon, tim->tm_mday, tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec); - return rtc_valid_tm(tim); + return 0; } static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm) diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 4ca4daa0b8f3..dd0364293bc0 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -122,7 +122,7 @@ static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm) */ mpc5121_rtc_update_smh(regs, tm); - return rtc_valid_tm(tm); + return 0; } static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c index 7334c44fa7c3..fcb9de5218b2 100644 --- a/drivers/rtc/rtc-mrst.c +++ b/drivers/rtc/rtc-mrst.c @@ -105,7 +105,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time) /* Adjust for the 1972/1900 */ time->tm_year += 72; time->tm_mon--; - return rtc_valid_tm(time); + return 0; } static int mrst_set_time(struct device *dev, struct rtc_time *time) @@ -122,7 +122,7 @@ static int mrst_set_time(struct device *dev, struct rtc_time *time) min = time->tm_min; sec = time->tm_sec; - if (yrs < 72 || yrs > 138) + if (yrs < 72 || yrs > 172) return -EINVAL; yrs -= 72; diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c index c1c5c4e3b3b4..0c72a2e8ec67 100644 --- a/drivers/rtc/rtc-msm6242.c +++ b/drivers/rtc/rtc-msm6242.c @@ -155,7 +155,7 @@ static int msm6242_read_time(struct device *dev, struct rtc_time *tm) msm6242_unlock(priv); - return rtc_valid_tm(tm); + return 0; } static int msm6242_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-mt7622.c b/drivers/rtc/rtc-mt7622.c index d79b9ae4d237..fd0cea722286 100644 --- a/drivers/rtc/rtc-mt7622.c +++ b/drivers/rtc/rtc-mt7622.c @@ -232,7 +232,7 @@ static int mtk_rtc_gettime(struct device *dev, struct rtc_time *tm) mtk_rtc_get_alarm_or_time(hw, tm, MTK_TC); - return rtc_valid_tm(tm); + return 0; } static int mtk_rtc_settime(struct device *dev, struct rtc_time *tm) @@ -307,6 +307,7 @@ static const struct of_device_id mtk_rtc_match[] = { { .compatible = "mediatek,soc-rtc" }, {}, }; +MODULE_DEVICE_TABLE(of, mtk_rtc_match); static int mtk_rtc_probe(struct platform_device *pdev) { diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 79bb28617d45..bc52dbb0c0e2 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -94,7 +94,7 @@ static int mv_rtc_read_time(struct device *dev, struct rtc_time *tm) /* hw counts from year 2000, but tm_year is relative to 1900 */ tm->tm_year = bcd2bin(year) + 100; - return rtc_valid_tm(tm); + return 0; } static int mv_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) @@ -223,7 +223,6 @@ static int __init mv_rtc_probe(struct platform_device *pdev) struct resource *res; struct rtc_plat_data *pdata; u32 rtc_time; - u32 rtc_date; int ret = 0; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); @@ -259,17 +258,6 @@ static int __init mv_rtc_probe(struct platform_device *pdev) } } - /* - * A date after January 19th, 2038 does not fit on 32 bits and - * will confuse the kernel and userspace. Reset to a sane date - * (January 1st, 2013) if we're after 2038. - */ - rtc_date = readl(pdata->ioaddr + RTC_DATE_REG_OFFS); - if (bcd2bin((rtc_date >> RTC_YEAR_OFFS) & 0xff) >= 38) { - dev_info(&pdev->dev, "invalid RTC date, resetting to January 1st, 2013\n"); - writel(0x130101, pdata->ioaddr + RTC_DATE_REG_OFFS); - } - pdata->irq = platform_get_irq(pdev, 0); platform_set_drvdata(pdev, pdata); diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c index 784221dfc9c7..9e14efb990b2 100644 --- a/drivers/rtc/rtc-mxc_v2.c +++ b/drivers/rtc/rtc-mxc_v2.c @@ -273,7 +273,7 @@ static const struct rtc_class_ops mxc_rtc_ops = { .alarm_irq_enable = mxc_rtc_alarm_irq_enable, }; -static int mxc_rtc_wait_for_flag(void *__iomem ioaddr, int flag) +static int mxc_rtc_wait_for_flag(void __iomem *ioaddr, int flag) { unsigned int timeout = REG_READ_TIMEOUT; diff --git a/drivers/rtc/rtc-nuc900.c b/drivers/rtc/rtc-nuc900.c index 4ed81117cf5f..7da664a77181 100644 --- a/drivers/rtc/rtc-nuc900.c +++ b/drivers/rtc/rtc-nuc900.c @@ -102,8 +102,8 @@ static int *check_rtc_access_enable(struct nuc900_rtc *nuc900_rtc) return NULL; } -static int nuc900_rtc_bcd2bin(unsigned int timereg, - unsigned int calreg, struct rtc_time *tm) +static void nuc900_rtc_bcd2bin(unsigned int timereg, + unsigned int calreg, struct rtc_time *tm) { tm->tm_mday = bcd2bin(calreg >> 0); tm->tm_mon = bcd2bin(calreg >> 8); @@ -112,8 +112,6 @@ static int nuc900_rtc_bcd2bin(unsigned int timereg, tm->tm_sec = bcd2bin(timereg >> 0); tm->tm_min = bcd2bin(timereg >> 8); tm->tm_hour = bcd2bin(timereg >> 16); - - return rtc_valid_tm(tm); } static void nuc900_rtc_bin2bcd(struct device *dev, struct rtc_time *settm, @@ -156,7 +154,9 @@ static int nuc900_rtc_read_time(struct device *dev, struct rtc_time *tm) timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TLR); clrval = __raw_readl(rtc->rtc_reg + REG_RTC_CLR); - return nuc900_rtc_bcd2bin(timeval, clrval, tm); + nuc900_rtc_bcd2bin(timeval, clrval, tm); + + return 0; } static int nuc900_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -189,7 +189,9 @@ static int nuc900_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) timeval = __raw_readl(rtc->rtc_reg + REG_RTC_TAR); carval = __raw_readl(rtc->rtc_reg + REG_RTC_CAR); - return nuc900_rtc_bcd2bin(timeval, carval, &alrm->time); + nuc900_rtc_bcd2bin(timeval, carval, &alrm->time); + + return rtc_valid_tm(&alrm->time); } static int nuc900_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 09ef802d6e54..39086398833e 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -273,9 +273,6 @@ 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) { - if (rtc_valid_tm(tm) != 0) - return -EINVAL; - tm->tm_sec = bin2bcd(tm->tm_sec); tm->tm_min = bin2bcd(tm->tm_min); tm->tm_hour = bin2bcd(tm->tm_hour); @@ -850,7 +847,6 @@ static int omap_rtc_probe(struct platform_device *pdev) rtc->rtc->ops = &omap_rtc_ops; omap_rtc_nvmem_config.priv = rtc; - rtc->rtc->nvmem_config = &omap_rtc_nvmem_config; /* handle periodic and alarm irqs */ ret = devm_request_irq(&pdev->dev, rtc->irq_timer, rtc_irq, 0, @@ -886,6 +882,8 @@ static int omap_rtc_probe(struct platform_device *pdev) if (ret) goto err; + rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config); + return 0; err: diff --git a/drivers/rtc/rtc-pcap.c b/drivers/rtc/rtc-pcap.c index c4433240d8a9..c05f524ba9af 100644 --- a/drivers/rtc/rtc-pcap.c +++ b/drivers/rtc/rtc-pcap.c @@ -95,7 +95,7 @@ static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time_to_tm(secs, tm); - return rtc_valid_tm(tm); + return 0; } static int pcap_rtc_set_mmss(struct device *dev, unsigned long secs) diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 8895f77726e8..e5222c5d8223 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -289,7 +289,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index f33447c5db85..e83be1852c2f 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -111,7 +111,7 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 00c31c91b245..ef72b0c389d7 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -135,7 +135,7 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec); - return rtc_valid_tm(tm); + return 0; } static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index a06dff994c83..49bcbb3d4a69 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -70,7 +70,7 @@ static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) s32 ret; /* start the clock */ - ctrl1 &= PCF85063_REG_CTRL1_STOP; + ctrl1 &= ~PCF85063_REG_CTRL1_STOP; ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); if (ret < 0) { @@ -81,8 +81,9 @@ static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) return 0; } -static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) +static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); int rc; u8 regs[7]; @@ -114,11 +115,12 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_year = bcd2bin(regs[6]); tm->tm_year += 100; - return rtc_valid_tm(tm); + return 0; } -static int pcf85063_set_datetime(struct i2c_client *client, 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); int rc; u8 regs[7]; u8 ctrl1; @@ -172,16 +174,6 @@ static int pcf85063_set_datetime(struct i2c_client *client, struct rtc_time *tm) return 0; } -static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return pcf85063_get_datetime(to_i2c_client(dev), tm); -} - -static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return pcf85063_set_datetime(to_i2c_client(dev), tm); -} - static const struct rtc_class_ops pcf85063_rtc_ops = { .read_time = pcf85063_rtc_read_time, .set_time = pcf85063_rtc_set_time diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index c312af0db729..453615f8ac9a 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c @@ -192,7 +192,7 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1; tm->tm_year = bcd2bin(regs[6]) + 100; - return rtc_valid_tm(tm); + return 0; } static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index ea04e9f0930b..c04a1edcd571 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -73,6 +73,43 @@ #define CTRL_RESETS 0x2f #define CTRL_RAM 0x40 +#define ALRM_SEC_A1E BIT(0) +#define ALRM_MIN_A1E BIT(1) +#define ALRM_HR_A1E BIT(2) +#define ALRM_DAY_A1E BIT(3) +#define ALRM_MON_A1E BIT(4) +#define ALRM_MIN_A2E BIT(5) +#define ALRM_HR_A2E BIT(6) +#define ALRM_DAY_A2E BIT(7) + +#define INT_WDIE BIT(0) +#define INT_BSIE BIT(1) +#define INT_TSRIE BIT(2) +#define INT_A2IE BIT(3) +#define INT_A1IE BIT(4) +#define INT_OIE BIT(5) +#define INT_PIE BIT(6) +#define INT_ILP BIT(7) + +#define FLAGS_TSR1F BIT(0) +#define FLAGS_TSR2F BIT(1) +#define FLAGS_TSR3F BIT(2) +#define FLAGS_BSF BIT(3) +#define FLAGS_WDF BIT(4) +#define FLAGS_A1F BIT(5) +#define FLAGS_A2F BIT(6) +#define FLAGS_PIF BIT(7) + +#define PIN_IO_INTAPM GENMASK(1, 0) +#define PIN_IO_INTA_CLK 0 +#define PIN_IO_INTA_BAT 1 +#define PIN_IO_INTA_OUT 2 +#define PIN_IO_INTA_HIZ 3 + +#define STOP_EN_STOP BIT(0) + +#define RESET_CPR 0xa4 + #define NVRAM_SIZE 0x40 static struct i2c_driver pcf85363_driver; @@ -80,7 +117,6 @@ static struct i2c_driver pcf85363_driver; struct pcf85363 { struct device *dev; struct rtc_device *rtc; - struct nvmem_config nvmem_cfg; struct regmap *regmap; }; @@ -116,8 +152,12 @@ static int pcf85363_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct pcf85363 *pcf85363 = dev_get_drvdata(dev); - unsigned char buf[DT_YEARS + 1]; - int len = sizeof(buf); + unsigned char tmp[11]; + unsigned char *buf = &tmp[2]; + int ret; + + tmp[0] = STOP_EN_STOP; + tmp[1] = RESET_CPR; buf[DT_100THS] = 0; buf[DT_SECS] = bin2bcd(tm->tm_sec); @@ -128,8 +168,116 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) buf[DT_MONTHS] = bin2bcd(tm->tm_mon + 1); buf[DT_YEARS] = bin2bcd(tm->tm_year % 100); - return regmap_bulk_write(pcf85363->regmap, DT_100THS, - buf, len); + ret = regmap_bulk_write(pcf85363->regmap, CTRL_STOP_EN, + tmp, sizeof(tmp)); + if (ret) + return ret; + + return regmap_write(pcf85363->regmap, CTRL_STOP_EN, 0); +} + +static int pcf85363_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf85363 *pcf85363 = dev_get_drvdata(dev); + unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1]; + unsigned int val; + int ret; + + ret = regmap_bulk_read(pcf85363->regmap, DT_SECOND_ALM1, 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]); + alrm->time.tm_mon = bcd2bin(buf[4]) - 1; + + ret = regmap_read(pcf85363->regmap, CTRL_INTA_EN, &val); + if (ret) + return ret; + + alrm->enabled = !!(val & INT_A1IE); + + return 0; +} + +static int _pcf85363_rtc_alarm_irq_enable(struct pcf85363 *pcf85363, unsigned + int enabled) +{ + unsigned int alarm_flags = ALRM_SEC_A1E | ALRM_MIN_A1E | ALRM_HR_A1E | + ALRM_DAY_A1E | ALRM_MON_A1E; + int ret; + + ret = regmap_update_bits(pcf85363->regmap, DT_ALARM_EN, alarm_flags, + enabled ? alarm_flags : 0); + if (ret) + return ret; + + ret = regmap_update_bits(pcf85363->regmap, CTRL_INTA_EN, + INT_A1IE, enabled ? INT_A1IE : 0); + + if (ret || enabled) + return ret; + + /* clear current flags */ + return regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0); +} + +static int pcf85363_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct pcf85363 *pcf85363 = dev_get_drvdata(dev); + + return _pcf85363_rtc_alarm_irq_enable(pcf85363, enabled); +} + +static int pcf85363_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct pcf85363 *pcf85363 = dev_get_drvdata(dev); + unsigned char buf[DT_MONTH_ALM1 - DT_SECOND_ALM1 + 1]; + 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] = bin2bcd(alrm->time.tm_mon + 1); + + /* + * Disable the alarm interrupt before changing the value to avoid + * spurious interrupts + */ + ret = _pcf85363_rtc_alarm_irq_enable(pcf85363, 0); + if (ret) + return ret; + + ret = regmap_bulk_write(pcf85363->regmap, DT_SECOND_ALM1, buf, + sizeof(buf)); + if (ret) + return ret; + + return _pcf85363_rtc_alarm_irq_enable(pcf85363, alrm->enabled); +} + +static irqreturn_t pcf85363_rtc_handle_irq(int irq, void *dev_id) +{ + struct pcf85363 *pcf85363 = i2c_get_clientdata(dev_id); + unsigned int flags; + int err; + + err = regmap_read(pcf85363->regmap, CTRL_FLAGS, &flags); + if (err) + return IRQ_NONE; + + if (flags & FLAGS_A1F) { + rtc_update_irq(pcf85363->rtc, 1, RTC_IRQF | RTC_AF); + regmap_update_bits(pcf85363->regmap, CTRL_FLAGS, FLAGS_A1F, 0); + return IRQ_HANDLED; + } + + return IRQ_NONE; } static const struct rtc_class_ops rtc_ops = { @@ -137,6 +285,14 @@ static const struct rtc_class_ops rtc_ops = { .set_time = pcf85363_rtc_set_time, }; +static const struct rtc_class_ops rtc_ops_alarm = { + .read_time = pcf85363_rtc_read_time, + .set_time = pcf85363_rtc_set_time, + .read_alarm = pcf85363_rtc_read_alarm, + .set_alarm = pcf85363_rtc_set_alarm, + .alarm_irq_enable = pcf85363_rtc_alarm_irq_enable, +}; + static int pcf85363_nvram_read(void *priv, unsigned int offset, void *val, size_t bytes) { @@ -158,12 +314,22 @@ static int pcf85363_nvram_write(void *priv, unsigned int offset, void *val, static const struct regmap_config regmap_config = { .reg_bits = 8, .val_bits = 8, + .max_register = 0x7f, }; static int pcf85363_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pcf85363 *pcf85363; + struct nvmem_config nvmem_cfg = { + .name = "pcf85363-", + .word_size = 1, + .stride = 1, + .size = NVRAM_SIZE, + .reg_read = pcf85363_nvram_read, + .reg_write = pcf85363_nvram_write, + }; + int ret; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -186,17 +352,28 @@ static int pcf85363_probe(struct i2c_client *client, if (IS_ERR(pcf85363->rtc)) return PTR_ERR(pcf85363->rtc); - pcf85363->nvmem_cfg.name = "pcf85363-"; - pcf85363->nvmem_cfg.word_size = 1; - pcf85363->nvmem_cfg.stride = 1; - pcf85363->nvmem_cfg.size = NVRAM_SIZE; - pcf85363->nvmem_cfg.reg_read = pcf85363_nvram_read; - pcf85363->nvmem_cfg.reg_write = pcf85363_nvram_write; - pcf85363->nvmem_cfg.priv = pcf85363; - pcf85363->rtc->nvmem_config = &pcf85363->nvmem_cfg; pcf85363->rtc->ops = &rtc_ops; - return rtc_register_device(pcf85363->rtc); + 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, + NULL, pcf85363_rtc_handle_irq, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "pcf85363", client); + if (ret) + dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n"); + else + pcf85363->rtc->ops = &rtc_ops_alarm; + } + + ret = rtc_register_device(pcf85363->rtc); + + nvmem_cfg.priv = pcf85363; + rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg); + + return ret; } static const struct of_device_id dev_ids[] = { diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c index 5cfb6df5c430..3c08eab4f1a8 100644 --- a/drivers/rtc/rtc-pic32.c +++ b/drivers/rtc/rtc-pic32.c @@ -175,7 +175,7 @@ static int pic32_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec); clk_disable(pdata->clk); - return rtc_valid_tm(rtc_tm); + return 0; } static int pic32_rtc_settime(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index fac835530671..29358a045925 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -74,16 +74,18 @@ struct pm8xxx_rtc { /* * Steps to write the RTC registers. * 1. Disable alarm if enabled. - * 2. Write 0x00 to LSB. - * 3. Write Byte[1], Byte[2], Byte[3] then Byte[0]. - * 4. Enable alarm if disabled in step 1. + * 2. Disable rtc if enabled. + * 3. Write 0x00 to LSB. + * 4. Write Byte[1], Byte[2], Byte[3] then Byte[0]. + * 5. Enable rtc if disabled in step 2. + * 6. Enable alarm if disabled in step 1. */ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) { int rc, i; unsigned long secs, irq_flags; - u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0; - unsigned int ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS], alarm_enabled = 0, rtc_disabled = 0; + unsigned int ctrl_reg, rtc_ctrl_reg; struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; @@ -92,23 +94,38 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) rtc_tm_to_time(tm, &secs); + dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); + for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { value[i] = secs & 0xFF; secs >>= 8; } - dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); - spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); - rc = regmap_read(rtc_dd->regmap, regs->ctrl, &ctrl_reg); + rc = regmap_read(rtc_dd->regmap, regs->alarm_ctrl, &ctrl_reg); if (rc) goto rtc_rw_fail; if (ctrl_reg & regs->alarm_en) { alarm_enabled = 1; ctrl_reg &= ~regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); + if (rc) { + dev_err(dev, "Write to RTC Alarm control register failed\n"); + goto rtc_rw_fail; + } + } + + /* Disable RTC H/w before writing on RTC register */ + rc = regmap_read(rtc_dd->regmap, regs->ctrl, &rtc_ctrl_reg); + if (rc) + goto rtc_rw_fail; + + if (rtc_ctrl_reg & PM8xxx_RTC_ENABLE) { + rtc_disabled = 1; + rtc_ctrl_reg &= ~PM8xxx_RTC_ENABLE; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); if (rc) { dev_err(dev, "Write to RTC control register failed\n"); goto rtc_rw_fail; @@ -137,11 +154,21 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) goto rtc_rw_fail; } + /* Enable RTC H/w after writing on RTC register */ + if (rtc_disabled) { + rtc_ctrl_reg |= PM8xxx_RTC_ENABLE; + rc = regmap_write(rtc_dd->regmap, regs->ctrl, rtc_ctrl_reg); + if (rc) { + dev_err(dev, "Write to RTC control register failed\n"); + goto rtc_rw_fail; + } + } + if (alarm_enabled) { ctrl_reg |= regs->alarm_en; - rc = regmap_write(rtc_dd->regmap, regs->ctrl, ctrl_reg); + rc = regmap_write(rtc_dd->regmap, regs->alarm_ctrl, ctrl_reg); if (rc) { - dev_err(dev, "Write to RTC control register failed\n"); + dev_err(dev, "Write to RTC Alarm control register failed\n"); goto rtc_rw_fail; } } @@ -190,12 +217,6 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time_to_tm(secs, tm); - rc = rtc_valid_tm(tm); - if (rc < 0) { - dev_err(dev, "Invalid time read from RTC\n"); - return rc; - } - dev_dbg(dev, "secs = %lu, h:m:s == %d:%d:%d, d/m/y = %d/%d/%d\n", secs, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_mday, tm->tm_mon, tm->tm_year); diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c index 6a8f5d758eac..347288bff438 100644 --- a/drivers/rtc/rtc-ps3.c +++ b/drivers/rtc/rtc-ps3.c @@ -41,7 +41,7 @@ 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); - return rtc_valid_tm(tm); + return 0; } static int ps3_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c index 500e8c8a2605..169704b2ce13 100644 --- a/drivers/rtc/rtc-r7301.c +++ b/drivers/rtc/rtc-r7301.c @@ -224,7 +224,7 @@ static int rtc7301_read_time(struct device *dev, struct rtc_time *tm) spin_unlock_irqrestore(&priv->lock, flags); - return err ? err : rtc_valid_tm(tm); + return err; } static int rtc7301_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index b6c5eb97051c..a39ccd1cf6e8 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c @@ -92,7 +92,7 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) * according to the data sheet. make sure they are valid. */ - return rtc_valid_tm(dt); + return 0; } static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index 35c9aada07c8..739c0d42e835 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c @@ -375,7 +375,6 @@ static int rk808_rtc_probe(struct platform_device *pdev) { struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); struct rk808_rtc *rk808_rtc; - struct rtc_time tm; int ret; rk808_rtc = devm_kzalloc(&pdev->dev, sizeof(*rk808_rtc), GFP_KERNEL); @@ -404,24 +403,13 @@ static int rk808_rtc_probe(struct platform_device *pdev) return ret; } - /* set init time */ - ret = rk808_rtc_readtime(&pdev->dev, &tm); - if (ret) { - dev_err(&pdev->dev, "Failed to read RTC time\n"); - return ret; - } - ret = rtc_valid_tm(&tm); - if (ret) - dev_warn(&pdev->dev, "invalid date/time\n"); - device_init_wakeup(&pdev->dev, 1); - rk808_rtc->rtc = devm_rtc_device_register(&pdev->dev, "rk808-rtc", - &rk808_rtc_ops, THIS_MODULE); - if (IS_ERR(rk808_rtc->rtc)) { - ret = PTR_ERR(rk808_rtc->rtc); - return ret; - } + rk808_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rk808_rtc->rtc)) + return PTR_ERR(rk808_rtc->rtc); + + rk808_rtc->rtc->ops = &rk808_rtc_ops; rk808_rtc->irq = platform_get_irq(pdev, 0); if (rk808_rtc->irq < 0) { @@ -438,9 +426,10 @@ static int rk808_rtc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Failed to request alarm IRQ %d: %d\n", rk808_rtc->irq, ret); + return ret; } - return ret; + return rtc_register_device(rk808_rtc->rtc); } static struct platform_driver rk808_rtc_driver = { diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 026035373ae6..f1c160fe7d37 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -64,7 +64,6 @@ struct rp5c01_priv { u32 __iomem *regs; struct rtc_device *rtc; spinlock_t lock; /* against concurrent RTC/NVRAM access */ - struct bin_attribute nvram_attr; }; static inline unsigned int rp5c01_read(struct rp5c01_priv *priv, @@ -116,7 +115,7 @@ static int rp5c01_read_time(struct device *dev, struct rtc_time *tm) rp5c01_unlock(priv); spin_unlock_irq(&priv->lock); - return rtc_valid_tm(tm); + return 0; } static int rp5c01_set_time(struct device *dev, struct rtc_time *tm) @@ -160,17 +159,15 @@ static const struct rtc_class_ops rp5c01_rtc_ops = { * byte is stored in BLOCK10, the low nibble in BLOCK11. */ -static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int rp5c01_nvram_read(void *_priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct rp5c01_priv *priv = dev_get_drvdata(dev); - ssize_t count; + struct rp5c01_priv *priv = _priv; + u8 *buf = val; spin_lock_irq(&priv->lock); - for (count = 0; count < size; count++) { + for (; bytes; bytes--) { u8 data; rp5c01_write(priv, @@ -187,20 +184,18 @@ static ssize_t rp5c01_nvram_read(struct file *filp, struct kobject *kobj, } spin_unlock_irq(&priv->lock); - return count; + return 0; } -static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int rp5c01_nvram_write(void *_priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct rp5c01_priv *priv = dev_get_drvdata(dev); - ssize_t count; + struct rp5c01_priv *priv = _priv; + u8 *buf = val; spin_lock_irq(&priv->lock); - for (count = 0; count < size; count++) { + for (; bytes; bytes--) { u8 data = *buf++; rp5c01_write(priv, @@ -216,7 +211,7 @@ static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj, } spin_unlock_irq(&priv->lock); - return count; + return 0; } static int __init rp5c01_rtc_probe(struct platform_device *dev) @@ -225,6 +220,14 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) struct rp5c01_priv *priv; struct rtc_device *rtc; int error; + struct nvmem_config nvmem_cfg = { + .name = "rp5c01_nvram", + .word_size = 1, + .stride = 1, + .size = RP5C01_MODE, + .reg_read = rp5c01_nvram_read, + .reg_write = rp5c01_nvram_write, + }; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) @@ -238,43 +241,31 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) if (!priv->regs) return -ENOMEM; - sysfs_bin_attr_init(&priv->nvram_attr); - priv->nvram_attr.attr.name = "nvram"; - priv->nvram_attr.attr.mode = S_IRUGO | S_IWUSR; - priv->nvram_attr.read = rp5c01_nvram_read; - priv->nvram_attr.write = rp5c01_nvram_write; - priv->nvram_attr.size = RP5C01_MODE; - spin_lock_init(&priv->lock); platform_set_drvdata(dev, priv); - rtc = devm_rtc_device_register(&dev->dev, "rtc-rp5c01", &rp5c01_rtc_ops, - THIS_MODULE); + rtc = devm_rtc_allocate_device(&dev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + + rtc->ops = &rp5c01_rtc_ops; + rtc->nvram_old_abi = true; + priv->rtc = rtc; - error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); + nvmem_cfg.priv = priv; + error = rtc_nvmem_register(rtc, &nvmem_cfg); if (error) return error; - return 0; -} - -static int __exit rp5c01_rtc_remove(struct platform_device *dev) -{ - struct rp5c01_priv *priv = platform_get_drvdata(dev); - - sysfs_remove_bin_file(&dev->dev.kobj, &priv->nvram_attr); - return 0; + return rtc_register_device(rtc); } static struct platform_driver rp5c01_rtc_driver = { .driver = { .name = "rtc-rp5c01", }, - .remove = __exit_p(rp5c01_rtc_remove), }; module_platform_driver_probe(rp5c01_rtc_driver, rp5c01_rtc_probe); diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 9a306983aaba..f2de8b17e7e3 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -135,11 +135,6 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_year = bcd2bin(rxbuf[RS5C348_REG_YEAR]) + ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); - if (rtc_valid_tm(tm) < 0) { - dev_err(&spi->dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } - return 0; } diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index d4eff8d7131f..c5038329058c 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -207,8 +207,9 @@ static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour) return bin2bcd(hour); } -static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) +static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct rs5c372 *rs5c = i2c_get_clientdata(client); int status = rs5c_get_regs(rs5c); @@ -234,12 +235,12 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - /* rtc might need initialization */ - return rtc_valid_tm(tm); + return 0; } -static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) +static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct rs5c372 *rs5c = i2c_get_clientdata(client); unsigned char buf[7]; int addr; @@ -305,17 +306,6 @@ static int rs5c372_get_trim(struct i2c_client *client, int *osc, int *trim) } #endif -static int rs5c372_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return rs5c372_get_datetime(to_i2c_client(dev), tm); -} - -static int rs5c372_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return rs5c372_set_datetime(to_i2c_client(dev), tm); -} - - static int rs5c_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct i2c_client *client = to_i2c_client(dev); @@ -581,7 +571,6 @@ static int rs5c372_probe(struct i2c_client *client, int err = 0; int smbus_mode = 0; struct rs5c372 *rs5c372; - struct rtc_time tm; dev_dbg(&client->dev, "%s\n", __func__); @@ -662,9 +651,6 @@ static int rs5c372_probe(struct i2c_client *client, goto exit; } - if (rs5c372_get_datetime(client, &tm) < 0) - dev_warn(&client->dev, "clock needs to be set\n"); - dev_info(&client->dev, "%s found, %s\n", ({ char *s; switch (rs5c372->type) { case rtc_r2025sd: s = "r2025sd"; break; diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index aae2576741a6..29fc3d210392 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -68,7 +68,6 @@ struct rv8803_data { struct mutex flags_lock; u8 ctrl; enum rv8803_type type; - struct nvmem_config nvmem_cfg; }; static int rv8803_read_reg(const struct i2c_client *client, u8 reg) @@ -528,6 +527,15 @@ static int rv8803_probe(struct i2c_client *client, struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); struct rv8803_data *rv8803; int err, flags; + struct nvmem_config nvmem_cfg = { + .name = "rv8803_nvram", + .word_size = 1, + .stride = 1, + .size = 1, + .reg_read = rv8803_nvram_read, + .reg_write = rv8803_nvram_write, + .priv = client, + }; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) { @@ -582,21 +590,6 @@ static int rv8803_probe(struct i2c_client *client, } } - rv8803->nvmem_cfg.name = "rv8803_nvram", - rv8803->nvmem_cfg.word_size = 1, - rv8803->nvmem_cfg.stride = 1, - rv8803->nvmem_cfg.size = 1, - rv8803->nvmem_cfg.reg_read = rv8803_nvram_read, - rv8803->nvmem_cfg.reg_write = rv8803_nvram_write, - rv8803->nvmem_cfg.priv = client; - - rv8803->rtc->ops = &rv8803_rtc_ops; - rv8803->rtc->nvmem_config = &rv8803->nvmem_cfg; - rv8803->rtc->nvram_old_abi = true; - err = rtc_register_device(rv8803->rtc); - if (err) - return err; - err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); if (err) return err; @@ -607,6 +600,14 @@ static int rv8803_probe(struct i2c_client *client, return err; } + rv8803->rtc->ops = &rv8803_rtc_ops; + rv8803->rtc->nvram_old_abi = true; + err = rtc_register_device(rv8803->rtc); + if (err) + return err; + + rtc_nvmem_register(rv8803->rtc, &nvmem_cfg); + rv8803->rtc->max_user_freq = 1; return 0; diff --git a/drivers/rtc/rtc-rx4581.c b/drivers/rtc/rtc-rx4581.c index de3fe4f8d133..c59a218bdd87 100644 --- a/drivers/rtc/rtc-rx4581.c +++ b/drivers/rtc/rtc-rx4581.c @@ -172,11 +172,7 @@ static int rx4581_get_datetime(struct device *dev, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - err = rtc_valid_tm(tm); - if (err < 0) - dev_err(dev, "retrieved date/time is not valid.\n"); - - return err; + return 0; } static int rx4581_set_datetime(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-rx6110.c b/drivers/rtc/rtc-rx6110.c index 7c9c08eab5e5..8e322d884cc2 100644 --- a/drivers/rtc/rtc-rx6110.c +++ b/drivers/rtc/rtc-rx6110.c @@ -252,7 +252,7 @@ static int rx6110_get_time(struct device *dev, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year); - return rtc_valid_tm(tm); + return 0; } static const struct reg_sequence rx6110_default_regs[] = { diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 5c5938ab3d86..7ddc22eb5b0f 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -138,7 +138,7 @@ static int rx8010_get_time(struct device *dev, struct rtc_time *dt) dt->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 100; dt->tm_wday = ffs(date[RX8010_WDAY - RX8010_SEC] & 0x7f); - return rtc_valid_tm(dt); + return 0; } static int rx8010_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-rx8025.c b/drivers/rtc/rtc-rx8025.c index 91857d8d2df8..41127adf5765 100644 --- a/drivers/rtc/rtc-rx8025.c +++ b/drivers/rtc/rtc-rx8025.c @@ -214,7 +214,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt) dt->tm_sec, dt->tm_min, dt->tm_hour, dt->tm_mday, dt->tm_mon, dt->tm_year); - return rtc_valid_tm(dt); + return 0; } static int rx8025_set_time(struct device *dev, struct rtc_time *dt) diff --git a/drivers/rtc/rtc-rx8581.c b/drivers/rtc/rtc-rx8581.c index 9998d7937688..32caadf912ca 100644 --- a/drivers/rtc/rtc-rx8581.c +++ b/drivers/rtc/rtc-rx8581.c @@ -164,11 +164,7 @@ static int rx8581_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - err = rtc_valid_tm(tm); - if (err < 0) - dev_err(&client->dev, "retrieved date/time is not valid.\n"); - - return err; + return 0; } static int rx8581_set_datetime(struct i2c_client *client, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 7067bca5c20d..77feb603cd4c 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -210,8 +210,9 @@ static int s35390a_reg2hr(struct s35390a *s35390a, char reg) return hour; } -static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) +static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct s35390a *s35390a = i2c_get_clientdata(client); int i, err; char buf[7], status; @@ -241,8 +242,9 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm) return err; } -static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) +static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) { + struct i2c_client *client = to_i2c_client(dev); struct s35390a *s35390a = i2c_get_clientdata(client); char buf[7], status; int i, err; @@ -271,11 +273,12 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm) tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } -static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) +static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { + struct i2c_client *client = to_i2c_client(dev); struct s35390a *s35390a = i2c_get_clientdata(client); char buf[3], sts = 0; int err, i; @@ -329,8 +332,9 @@ static int s35390a_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) return err; } -static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) +static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { + struct i2c_client *client = to_i2c_client(dev); struct s35390a *s35390a = i2c_get_clientdata(client); char buf[3], sts; int i, err; @@ -384,26 +388,6 @@ static int s35390a_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alm) return 0; } -static int s35390a_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - return s35390a_read_alarm(to_i2c_client(dev), alm); -} - -static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) -{ - return s35390a_set_alarm(to_i2c_client(dev), alm); -} - -static int s35390a_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return s35390a_get_datetime(to_i2c_client(dev), tm); -} - -static int s35390a_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return s35390a_set_datetime(to_i2c_client(dev), tm); -} - static int s35390a_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { @@ -450,7 +434,6 @@ static int s35390a_probe(struct i2c_client *client, int err, err_read; unsigned int i; struct s35390a *s35390a; - struct rtc_time tm; char buf, status1; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { @@ -508,9 +491,6 @@ static int s35390a_probe(struct i2c_client *client, } } - if (err_read > 0 || s35390a_get_datetime(client, &tm) < 0) - dev_warn(&client->dev, "clock needs to be set\n"); - device_set_wakeup_capable(&client->dev, 1); s35390a->rtc = devm_rtc_device_register(&client->dev, diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index a8992c227f61..75c8c5033e08 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c @@ -232,7 +232,7 @@ retry_get_time: rtc_tm->tm_mon -= 1; - return rtc_valid_tm(rtc_tm); + return 0; } static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 0477678d968f..8428455432ca 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -38,6 +38,19 @@ */ #define UDR_READ_RETRY_CNT 5 +enum { + RTC_SEC = 0, + RTC_MIN, + RTC_HOUR, + RTC_WEEKDAY, + RTC_DATE, + RTC_MONTH, + RTC_YEAR1, + RTC_YEAR2, + /* Make sure this is always the last enum name. */ + RTC_MAX_NUM_TIME_REGS +}; + /* * Registers used by the driver which are different between chipsets. * @@ -367,7 +380,7 @@ static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data) static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; int ret; if (info->regs->read_time_udr_mask) { @@ -407,13 +420,13 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm) 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; int ret = 0; switch (info->device_type) { @@ -450,7 +463,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm) static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; unsigned int val; int ret, i; @@ -500,7 +513,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) { - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; int ret, i; struct rtc_time tm; @@ -545,7 +558,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info) static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) { int ret; - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; u8 alarm0_conf; struct rtc_time tm; @@ -598,7 +611,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info) static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct s5m_rtc_info *info = dev_get_drvdata(dev); - u8 data[info->regs->regs_count]; + u8 data[RTC_MAX_NUM_TIME_REGS]; int ret; switch (info->device_type) { diff --git a/drivers/rtc/rtc-sc27xx.c b/drivers/rtc/rtc-sc27xx.c index d544d5268757..00d87d138984 100644 --- a/drivers/rtc/rtc-sc27xx.c +++ b/drivers/rtc/rtc-sc27xx.c @@ -376,7 +376,7 @@ static int sprd_rtc_read_time(struct device *dev, struct rtc_time *tm) return ret; rtc_time64_to_tm(secs, tm); - return rtc_valid_tm(tm); + return 0; } static int sprd_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 6c2d3989f967..4e8ab370ce63 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -414,7 +414,7 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_sec, tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); - return rtc_valid_tm(tm); + return 0; } static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 7367f617145c..2a9e151cae99 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -204,23 +204,6 @@ static int sirfsoc_rtc_set_time(struct device *dev, return 0; } -static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd, - unsigned long arg) -{ - switch (cmd) { - case RTC_PIE_ON: - case RTC_PIE_OFF: - case RTC_UIE_ON: - case RTC_UIE_OFF: - case RTC_AIE_ON: - case RTC_AIE_OFF: - return 0; - - default: - return -ENOIOCTLCMD; - } -} - static int sirfsoc_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { @@ -250,7 +233,6 @@ static const struct rtc_class_ops sirfsoc_rtc_ops = { .set_time = sirfsoc_rtc_set_time, .read_alarm = sirfsoc_rtc_read_alarm, .set_alarm = sirfsoc_rtc_set_alarm, - .ioctl = sirfsoc_rtc_ioctl, .alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable }; diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index d8ef9e052c4f..9af591d5223c 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -132,20 +132,23 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct snvs_rtc_data *data = dev_get_drvdata(dev); unsigned long time; + int ret; rtc_tm_to_time(tm, &time); /* Disable RTC first */ - snvs_rtc_enable(data, false); + ret = snvs_rtc_enable(data, false); + if (ret) + return ret; /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH); regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH)); /* Enable RTC again */ - snvs_rtc_enable(data, true); + ret = snvs_rtc_enable(data, true); - return 0; + return ret; } static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -288,7 +291,11 @@ static int snvs_rtc_probe(struct platform_device *pdev) regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff); /* Enable RTC */ - snvs_rtc_enable(data, true); + ret = snvs_rtc_enable(data, true); + if (ret) { + dev_err(&pdev->dev, "failed to enable rtc %d\n", ret); + goto error_rtc_device_register; + } device_init_wakeup(&pdev->dev, true); diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index e377f42abae7..0567944fd4f8 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -170,18 +170,14 @@ static irqreturn_t spear_rtc_irq(int irq, void *dev_id) } -static int tm2bcd(struct rtc_time *tm) +static void tm2bcd(struct rtc_time *tm) { - if (rtc_valid_tm(tm) != 0) - return -EINVAL; tm->tm_sec = bin2bcd(tm->tm_sec); tm->tm_min = bin2bcd(tm->tm_min); tm->tm_hour = bin2bcd(tm->tm_hour); tm->tm_mday = bin2bcd(tm->tm_mday); tm->tm_mon = bin2bcd(tm->tm_mon + 1); tm->tm_year = bin2bcd(tm->tm_year); - - return 0; } static void bcd2tm(struct rtc_time *tm) @@ -237,8 +233,7 @@ static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm) struct spear_rtc_config *config = dev_get_drvdata(dev); unsigned int time, date; - if (tm2bcd(tm) < 0) - return -EINVAL; + tm2bcd(tm); rtc_wait_not_busy(config); time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) | @@ -295,8 +290,7 @@ static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) unsigned int time, date; int err; - if (tm2bcd(&alm->time) < 0) - return -EINVAL; + tm2bcd(&alm->time); rtc_wait_not_busy(config); diff --git a/drivers/rtc/rtc-st-lpc.c b/drivers/rtc/rtc-st-lpc.c index 82b0af159a28..d5222667f892 100644 --- a/drivers/rtc/rtc-st-lpc.c +++ b/drivers/rtc/rtc-st-lpc.c @@ -195,7 +195,6 @@ static int st_rtc_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct st_rtc *rtc; struct resource *res; - struct rtc_time tm_check; uint32_t mode; int ret = 0; @@ -254,21 +253,6 @@ static int st_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - /* - * The RTC-LPC is able to manage date.year > 2038 - * but currently the kernel can not manage this date! - * If the RTC-LPC has a date.year > 2038 then - * it's set to the epoch "Jan 1st 2000" - */ - st_rtc_read_time(&pdev->dev, &tm_check); - - if (tm_check.tm_year >= (2038 - 1900)) { - memset(&tm_check, 0, sizeof(tm_check)); - tm_check.tm_year = 100; - tm_check.tm_mday = 1; - st_rtc_set_time(&pdev->dev, &tm_check); - } - rtc->rtc_dev = rtc_device_register("st-lpc-rtc", &pdev->dev, &st_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtc_dev)) { diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c index 7fc36973fa33..a7d49329d626 100644 --- a/drivers/rtc/rtc-starfire.c +++ b/drivers/rtc/rtc-starfire.c @@ -28,7 +28,7 @@ static u32 starfire_get_time(void) static int starfire_read_time(struct device *dev, struct rtc_time *tm) { rtc_time_to_tm(starfire_get_time(), tm); - return rtc_valid_tm(tm); + return 0; } static const struct rtc_class_ops starfire_rtc_ops = { diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index a456cb6177ea..e70b78d17a98 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -129,10 +129,6 @@ static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm) /* year is 1900 + tm->tm_year */ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900; - if (rtc_valid_tm(tm) < 0) { - dev_err(dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } return 0; } @@ -242,46 +238,30 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = { .alarm_irq_enable = stk17ta8_rtc_alarm_irq_enable, }; -static ssize_t stk17ta8_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, - loff_t pos, size_t size) +static int stk17ta8_nvram_read(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + struct rtc_plat_data *pdata = priv; void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) *buf++ = readb(ioaddr + pos++); - return count; + return 0; } -static ssize_t stk17ta8_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, - loff_t pos, size_t size) +static int stk17ta8_nvram_write(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct platform_device *pdev = to_platform_device(dev); - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); + struct rtc_plat_data *pdata = priv; void __iomem *ioaddr = pdata->ioaddr; - ssize_t count; + u8 *buf = val; - for (count = 0; count < size; count++) + for (; bytes; bytes--) writeb(*buf++, ioaddr + pos++); - return count; + return 0; } -static struct bin_attribute stk17ta8_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - .size = RTC_OFFSET, - .read = stk17ta8_nvram_read, - .write = stk17ta8_nvram_write, -}; - static int stk17ta8_rtc_probe(struct platform_device *pdev) { struct resource *res; @@ -290,6 +270,14 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) struct rtc_plat_data *pdata; void __iomem *ioaddr; int ret = 0; + struct nvmem_config nvmem_cfg = { + .name = "stk17ta8_nvram", + .word_size = 1, + .stride = 1, + .size = RTC_OFFSET, + .reg_read = stk17ta8_nvram_read, + .reg_write = stk17ta8_nvram_write, + }; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -328,24 +316,19 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) } } - pdata->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &stk17ta8_rtc_ops, THIS_MODULE); + pdata->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(pdata->rtc)) return PTR_ERR(pdata->rtc); - ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); + pdata->rtc->ops = &stk17ta8_rtc_ops; + pdata->rtc->nvram_old_abi = true; - return ret; -} + nvmem_cfg.priv = pdata; + ret = rtc_nvmem_register(pdata->rtc, &nvmem_cfg); + if (ret) + return ret; -static int stk17ta8_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); - if (pdata->irq > 0) - writeb(0, pdata->ioaddr + RTC_INTERRUPTS); - return 0; + return rtc_register_device(pdata->rtc); } /* work with hotplug and coldplug */ @@ -353,7 +336,6 @@ MODULE_ALIAS("platform:stk17ta8"); static struct platform_driver stk17ta8_rtc_driver = { .probe = stk17ta8_rtc_probe, - .remove = stk17ta8_rtc_remove, .driver = { .name = "stk17ta8", }, diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 5bc28eed1adf..2e6fb275acc8 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -349,7 +349,7 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) */ rtc_tm->tm_year += SUN6I_YEAR_OFF; - return rtc_valid_tm(rtc_tm); + return 0; } static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) diff --git a/drivers/rtc/rtc-sunxi.c b/drivers/rtc/rtc-sunxi.c index abada609ddc7..dadbf8b324ad 100644 --- a/drivers/rtc/rtc-sunxi.c +++ b/drivers/rtc/rtc-sunxi.c @@ -261,7 +261,7 @@ static int sunxi_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) */ rtc_tm->tm_year += SUNXI_YEAR_OFF(chip->data_year); - return rtc_valid_tm(rtc_tm); + return 0; } static int sunxi_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 92ff2edb86a6..454da38c6012 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c @@ -248,6 +248,14 @@ offset_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(offset); +static ssize_t +range_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "[%lld,%llu]\n", to_rtc_device(dev)->range_min, + to_rtc_device(dev)->range_max); +} +static DEVICE_ATTR_RO(range); + static struct attribute *rtc_attrs[] = { &dev_attr_name.attr, &dev_attr_date.attr, @@ -257,6 +265,7 @@ static struct attribute *rtc_attrs[] = { &dev_attr_hctosys.attr, &dev_attr_wakealarm.attr, &dev_attr_offset.attr, + &dev_attr_range.attr, NULL, }; @@ -286,6 +295,9 @@ static umode_t rtc_attr_is_visible(struct kobject *kobj, } else if (attr == &dev_attr_offset.attr) { if (!rtc->ops->set_offset) mode = 0; + } else if (attr == &dev_attr_range.attr) { + if (!(rtc->range_max - rtc->range_min)) + mode = 0; } return mode; diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index d30d57b048d3..66efff60c4d5 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -144,10 +144,6 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) int ret; /* convert tm to seconds. */ - ret = rtc_valid_tm(tm); - if (ret) - return ret; - rtc_tm_to_time(tm, &sec); dev_vdbg(dev, "time set to %lu. %d/%d/%d %d:%02u:%02u\n", diff --git a/drivers/rtc/rtc-tps6586x.c b/drivers/rtc/rtc-tps6586x.c index a3418a8a3796..d7785ae0a2b4 100644 --- a/drivers/rtc/rtc-tps6586x.c +++ b/drivers/rtc/rtc-tps6586x.c @@ -90,7 +90,7 @@ static int tps6586x_rtc_read_time(struct device *dev, struct rtc_time *tm) seconds = ticks >> 10; seconds += rtc->epoch_start; rtc_time_to_tm(seconds, tm); - return rtc_valid_tm(tm); + return 0; } static int tps6586x_rtc_set_time(struct device *dev, struct rtc_time *tm) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 560d9a5e0225..08dbefc79520 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -14,7 +14,30 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/gfp.h> -#include <asm/txx9/tx4939.h> + +#define TX4939_RTCCTL_ALME 0x00000080 +#define TX4939_RTCCTL_ALMD 0x00000040 +#define TX4939_RTCCTL_BUSY 0x00000020 + +#define TX4939_RTCCTL_COMMAND 0x00000007 +#define TX4939_RTCCTL_COMMAND_NOP 0x00000000 +#define TX4939_RTCCTL_COMMAND_GETTIME 0x00000001 +#define TX4939_RTCCTL_COMMAND_SETTIME 0x00000002 +#define TX4939_RTCCTL_COMMAND_GETALARM 0x00000003 +#define TX4939_RTCCTL_COMMAND_SETALARM 0x00000004 + +#define TX4939_RTCTBC_PM 0x00000080 +#define TX4939_RTCTBC_COMP 0x0000007f + +#define TX4939_RTC_REG_RAMSIZE 0x00000100 +#define TX4939_RTC_REG_RWBSIZE 0x00000006 + +struct tx4939_rtc_reg { + __u32 ctl; + __u32 adr; + __u32 dat; + __u32 tbc; +}; struct tx4939rtc_plat_data { struct rtc_device *rtc; @@ -86,9 +109,10 @@ static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) for (i = 2; i < 6; i++) buf[i] = __raw_readl(&rtcreg->dat); spin_unlock_irq(&pdata->lock); - sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; + sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) | + (buf[3] << 8) | buf[2]; rtc_time_to_tm(sec, tm); - return rtc_valid_tm(tm); + return 0; } static int tx4939_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -147,7 +171,8 @@ static int tx4939_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) alrm->enabled = (ctl & TX4939_RTCCTL_ALME) ? 1 : 0; alrm->pending = (ctl & TX4939_RTCCTL_ALMD) ? 1 : 0; spin_unlock_irq(&pdata->lock); - sec = (buf[5] << 24) | (buf[4] << 16) | (buf[3] << 8) | buf[2]; + sec = ((unsigned long)buf[5] << 24) | (buf[4] << 16) | + (buf[3] << 8) | buf[2]; rtc_time_to_tm(sec, &alrm->time); return rtc_valid_tm(&alrm->time); } @@ -189,58 +214,52 @@ static const struct rtc_class_ops tx4939_rtc_ops = { .alarm_irq_enable = tx4939_rtc_alarm_irq_enable, }; -static ssize_t tx4939_rtc_nvram_read(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int tx4939_nvram_read(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = priv; struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; - ssize_t count; + u8 *buf = val; spin_lock_irq(&pdata->lock); - for (count = 0; count < size; count++) { + for (; bytes; bytes--) { __raw_writel(pos++, &rtcreg->adr); *buf++ = __raw_readl(&rtcreg->dat); } spin_unlock_irq(&pdata->lock); - return count; + return 0; } -static ssize_t tx4939_rtc_nvram_write(struct file *filp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t size) +static int tx4939_nvram_write(void *priv, unsigned int pos, void *val, + size_t bytes) { - struct device *dev = container_of(kobj, struct device, kobj); - struct tx4939rtc_plat_data *pdata = get_tx4939rtc_plat_data(dev); + struct tx4939rtc_plat_data *pdata = priv; struct tx4939_rtc_reg __iomem *rtcreg = pdata->rtcreg; - ssize_t count; + u8 *buf = val; spin_lock_irq(&pdata->lock); - for (count = 0; count < size; count++) { + for (; bytes; bytes--) { __raw_writel(pos++, &rtcreg->adr); __raw_writel(*buf++, &rtcreg->dat); } spin_unlock_irq(&pdata->lock); - return count; + return 0; } -static struct bin_attribute tx4939_rtc_nvram_attr = { - .attr = { - .name = "nvram", - .mode = S_IRUGO | S_IWUSR, - }, - .size = TX4939_RTC_REG_RAMSIZE, - .read = tx4939_rtc_nvram_read, - .write = tx4939_rtc_nvram_write, -}; - static int __init tx4939_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; struct tx4939rtc_plat_data *pdata; struct resource *res; int irq, ret; + struct nvmem_config nvmem_cfg = { + .name = "rv8803_nvram", + .word_size = 4, + .stride = 4, + .size = TX4939_RTC_REG_RAMSIZE, + .reg_read = tx4939_nvram_read, + .reg_write = tx4939_nvram_write, + }; irq = platform_get_irq(pdev, 0); if (irq < 0) @@ -260,21 +279,27 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev) if (devm_request_irq(&pdev->dev, irq, tx4939_rtc_interrupt, 0, pdev->name, &pdev->dev) < 0) return -EBUSY; - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &tx4939_rtc_ops, THIS_MODULE); + rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + + rtc->ops = &tx4939_rtc_ops; + rtc->nvram_old_abi = true; + pdata->rtc = rtc; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); - return ret; + nvmem_cfg.priv = pdata; + ret = rtc_nvmem_register(rtc, &nvmem_cfg); + if (ret) + return ret; + + return rtc_register_device(rtc); } static int __exit tx4939_rtc_remove(struct platform_device *pdev) { struct tx4939rtc_plat_data *pdata = platform_get_drvdata(pdev); - sysfs_remove_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); spin_lock_irq(&pdata->lock); tx4939_rtc_cmd(pdata->rtcreg, TX4939_RTCCTL_COMMAND_NOP); spin_unlock_irq(&pdata->lock); diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 75aea4c4d334..7b824dabf104 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c @@ -156,7 +156,7 @@ static int wm831x_rtc_readtime(struct device *dev, struct rtc_time *tm) u32 time = (time1[0] << 16) | time1[1]; rtc_time_to_tm(time, tm); - return rtc_valid_tm(tm); + return 0; } } while (++count < WM831X_GET_TIME_RETRIES); diff --git a/drivers/rtc/rtc-xgene.c b/drivers/rtc/rtc-xgene.c index 0c34d3b81279..153820876a82 100644 --- a/drivers/rtc/rtc-xgene.c +++ b/drivers/rtc/rtc-xgene.c @@ -60,7 +60,7 @@ 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); - return rtc_valid_tm(tm); + return 0; } static int xgene_rtc_set_mmss(struct device *dev, unsigned long secs) diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index da18a8ae3c1d..fba994dc31eb 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -122,7 +122,7 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm) rtc_time64_to_tm(read_time, tm); } - return rtc_valid_tm(tm); + return 0; } static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) diff --git a/drivers/rtc/systohc.c b/drivers/rtc/systohc.c index 0c177647ea6c..718293d72426 100644 --- a/drivers/rtc/systohc.c +++ b/drivers/rtc/systohc.c @@ -20,7 +20,7 @@ * cases. * * -EPROTO is returned if now.tv_nsec is not close enough to *target_nsec. - ( + * * If temporary failure is indicated the caller should try again 'soon' */ int rtc_set_ntp_time(struct timespec64 now, unsigned long *target_nsec) diff --git a/include/linux/mfd/samsung/rtc.h b/include/linux/mfd/samsung/rtc.h index 48c3c5be7eb1..9ed2871ea335 100644 --- a/include/linux/mfd/samsung/rtc.h +++ b/include/linux/mfd/samsung/rtc.h @@ -141,15 +141,4 @@ enum s2mps_rtc_reg { #define WTSR_ENABLE_SHIFT 6 #define WTSR_ENABLE_MASK (1 << WTSR_ENABLE_SHIFT) -enum { - RTC_SEC = 0, - RTC_MIN, - RTC_HOUR, - RTC_WEEKDAY, - RTC_DATE, - RTC_MONTH, - RTC_YEAR1, - RTC_YEAR2, -}; - #endif /* __LINUX_MFD_SEC_RTC_H */ diff --git a/include/linux/rtc.h b/include/linux/rtc.h index fc6c90b57be0..4c007f69082f 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -145,12 +145,17 @@ struct rtc_device { bool registered; - struct nvmem_config *nvmem_config; struct nvmem_device *nvmem; /* Old ABI support */ bool nvram_old_abi; struct bin_attribute *nvram; + time64_t range_min; + timeu64_t range_max; + time64_t start_secs; + time64_t offset_secs; + bool set_start_time; + #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL struct work_struct uie_task; struct timer_list uie_timer; @@ -164,6 +169,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_2000 946684800LL /* 2000-01-01 00:00:00 */ +#define RTC_TIMESTAMP_END_2099 4102444799LL /* 2099-12-31 23:59:59 */ + extern struct rtc_device *rtc_device_register(const char *name, struct device *dev, const struct rtc_class_ops *ops, @@ -212,10 +222,6 @@ void rtc_aie_update_irq(void *private); void rtc_uie_update_irq(void *private); enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer); -int rtc_register(rtc_task_t *task); -int rtc_unregister(rtc_task_t *task); -int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); - void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data); int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, ktime_t expires, ktime_t period); @@ -271,4 +277,17 @@ extern int rtc_hctosys_ret; #define rtc_hctosys_ret -ENODEV #endif +#ifdef CONFIG_RTC_NVMEM +int rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config); +void rtc_nvmem_unregister(struct rtc_device *rtc); +#else +static inline int rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config) +{ + return -ENODEV; +} +static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} +#endif + #endif /* _LINUX_RTC_H_ */ diff --git a/include/trace/events/rtc.h b/include/trace/events/rtc.h new file mode 100644 index 000000000000..621333f1c890 --- /dev/null +++ b/include/trace/events/rtc.h @@ -0,0 +1,206 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM rtc + +#if !defined(_TRACE_RTC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_RTC_H + +#include <linux/rtc.h> +#include <linux/tracepoint.h> + +DECLARE_EVENT_CLASS(rtc_time_alarm_class, + + TP_PROTO(time64_t secs, int err), + + TP_ARGS(secs, err), + + TP_STRUCT__entry( + __field(time64_t, secs) + __field(int, err) + ), + + TP_fast_assign( + __entry->secs = secs; + __entry->err = err; + ), + + TP_printk("UTC (%lld) (%d)", + __entry->secs, __entry->err + ) +); + +DEFINE_EVENT(rtc_time_alarm_class, rtc_set_time, + + TP_PROTO(time64_t secs, int err), + + TP_ARGS(secs, err) +); + +DEFINE_EVENT(rtc_time_alarm_class, rtc_read_time, + + TP_PROTO(time64_t secs, int err), + + TP_ARGS(secs, err) +); + +DEFINE_EVENT(rtc_time_alarm_class, rtc_set_alarm, + + TP_PROTO(time64_t secs, int err), + + TP_ARGS(secs, err) +); + +DEFINE_EVENT(rtc_time_alarm_class, rtc_read_alarm, + + TP_PROTO(time64_t secs, int err), + + TP_ARGS(secs, err) +); + +TRACE_EVENT(rtc_irq_set_freq, + + TP_PROTO(int freq, int err), + + TP_ARGS(freq, err), + + TP_STRUCT__entry( + __field(int, freq) + __field(int, err) + ), + + TP_fast_assign( + __entry->freq = freq; + __entry->err = err; + ), + + TP_printk("set RTC periodic IRQ frequency:%u (%d)", + __entry->freq, __entry->err + ) +); + +TRACE_EVENT(rtc_irq_set_state, + + TP_PROTO(int enabled, int err), + + TP_ARGS(enabled, err), + + TP_STRUCT__entry( + __field(int, enabled) + __field(int, err) + ), + + TP_fast_assign( + __entry->enabled = enabled; + __entry->err = err; + ), + + TP_printk("%s RTC 2^N Hz periodic IRQs (%d)", + __entry->enabled ? "enable" : "disable", + __entry->err + ) +); + +TRACE_EVENT(rtc_alarm_irq_enable, + + TP_PROTO(unsigned int enabled, int err), + + TP_ARGS(enabled, err), + + TP_STRUCT__entry( + __field(unsigned int, enabled) + __field(int, err) + ), + + TP_fast_assign( + __entry->enabled = enabled; + __entry->err = err; + ), + + TP_printk("%s RTC alarm IRQ (%d)", + __entry->enabled ? "enable" : "disable", + __entry->err + ) +); + +DECLARE_EVENT_CLASS(rtc_offset_class, + + TP_PROTO(long offset, int err), + + TP_ARGS(offset, err), + + TP_STRUCT__entry( + __field(long, offset) + __field(int, err) + ), + + TP_fast_assign( + __entry->offset = offset; + __entry->err = err; + ), + + TP_printk("RTC offset: %ld (%d)", + __entry->offset, __entry->err + ) +); + +DEFINE_EVENT(rtc_offset_class, rtc_set_offset, + + TP_PROTO(long offset, int err), + + TP_ARGS(offset, err) +); + +DEFINE_EVENT(rtc_offset_class, rtc_read_offset, + + TP_PROTO(long offset, int err), + + TP_ARGS(offset, err) +); + +DECLARE_EVENT_CLASS(rtc_timer_class, + + TP_PROTO(struct rtc_timer *timer), + + TP_ARGS(timer), + + TP_STRUCT__entry( + __field(struct rtc_timer *, timer) + __field(ktime_t, expires) + __field(ktime_t, period) + ), + + TP_fast_assign( + __entry->timer = timer; + __entry->expires = timer->node.expires; + __entry->period = timer->period; + ), + + TP_printk("RTC timer:(%p) expires:%lld period:%lld", + __entry->timer, __entry->expires, __entry->period + ) +); + +DEFINE_EVENT(rtc_timer_class, rtc_timer_enqueue, + + TP_PROTO(struct rtc_timer *timer), + + TP_ARGS(timer) +); + +DEFINE_EVENT(rtc_timer_class, rtc_timer_dequeue, + + TP_PROTO(struct rtc_timer *timer), + + TP_ARGS(timer) +); + +DEFINE_EVENT(rtc_timer_class, rtc_timer_fired, + + TP_PROTO(struct rtc_timer *timer), + + TP_ARGS(timer) +); + +#endif /* _TRACE_RTC_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> |