From 29a1f599c0cc37004f92ba455d1ccda3db0b6a94 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 14 Dec 2017 13:31:43 +0800 Subject: rtc: Add tracepoints for RTC system It will be more helpful to add some tracepoints to track RTC actions when debugging RTC driver. Below sample is that we set/read the RTC time, then set 2 alarms, so we can see the trace logs: set/read RTC time: kworker/0:1-67 [000] 21.814245: rtc_set_time: UTC (1510301580) (0) kworker/0:1-67 [000] 21.814312: rtc_read_time: UTC (1510301580) (0) set the first alarm timer: kworker/0:1-67 [000] 21.829238: rtc_timer_enqueue: RTC timer:(ffffffc15eb49bc8) expires:1510301700000000000 period:0 kworker/0:1-67 [000] 22.018279: rtc_set_alarm: UTC (1510301700) (0) set the second alarm timer: kworker/0:1-67 [000] 22.230284: rtc_timer_enqueue: RTC timer:(ffffff80088e6430) expires:1510301820000000000 period:0 the first alarm timer was expired: kworker/0:1-67 [000] 145.155584: rtc_timer_dequeue: RTC timer:(ffffffc15eb49bc8) expires:1510301700000000000 period:0 kworker/0:1-67 [000] 145.155593: rtc_timer_fired: RTC timer:(ffffffc15eb49bc8) expires:1510301700000000000 period:0 kworker/0:1-67 [000] 145.172504: rtc_set_alarm: UTC (1510301820) (0) the second alarm timer was expired: kworker/0:1-67 [000] 269.102353: rtc_timer_dequeue: RTC timer:(ffffff80088e6430) expires:1510301820000000000 period:0 kworker/0:1-67 [000] 269.102360: rtc_timer_fired: RTC timer:(ffffff80088e6430) expires:1510301820000000000 period:0 disable alarm irq: kworker/0:1-67 [000] 269.102469: rtc_alarm_irq_enable: disable RTC alarm IRQ (0) Signed-off-by: Baolin Wang Signed-off-by: Alexandre Belloni --- drivers/rtc/interface.c | 30 +++++++ include/trace/events/rtc.h | 206 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 include/trace/events/rtc.h diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 672b192f8153..7e253be19ba7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -17,6 +17,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + 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); @@ -53,6 +56,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); @@ -87,6 +92,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 +126,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 +325,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); @@ -352,6 +362,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; } @@ -406,6 +417,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 +447,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 +723,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 +761,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 +797,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 +809,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 +823,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 +842,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 +893,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 +927,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 +1018,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 +1053,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/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 +#include + +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 -- cgit v1.2.1 From 36d46cdb43efea74043e29e2a62b13e9aca31452 Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Mon, 25 Dec 2017 19:10:37 +0800 Subject: rtc: Fix overflow when converting time64_t to rtc_time If we convert one large time values to rtc_time, in the original formula 'days * 86400' can be overflowed in 'unsigned int' type to make the formula get one incorrect remain seconds value. Thus we can use div_s64_rem() function to avoid this situation. Signed-off-by: Baolin Wang Acked-by: Arnd Bergmann Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-lib.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 1ae7da5cfc60..ad5bb21908e5 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; -- cgit v1.2.1 From 82d632b85eb89f97051530f556cb49ee1c04bde7 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 16 Jan 2018 14:45:21 +0000 Subject: rtc: goldfish: Add missing MODULE_LICENSE Fix the following warning in MIPS allmodconfig by adding a MODULE_LICENSE() at the end of rtc-goldfish.c, based on the file header comment which says GNU General Public License version 2: WARNING: modpost: missing MODULE_LICENSE() in drivers/rtc/rtc-goldfish.o Fixes: f22d9cdcb5eb ("rtc: goldfish: Add RTC driver for Android emulator") Signed-off-by: James Hogan Cc: Miodrag Dinic Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: linux-rtc@vger.kernel.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-goldfish.c | 2 ++ 1 file changed, 2 insertions(+) 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"); -- cgit v1.2.1 From 5134d2fd9fe1278ecb309421275d88b6c80ebddd Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 23 Jan 2018 10:17:27 +0000 Subject: rtc: ds1302: remove redundant initializations of pointer bp Pointe bp is being initialized and this value is never read, it is being updated to the same value later just before it is going to be used. Remove the initialization as it is never read and keep the setting of bp closer to the use of bp. Cleans up clang warnings: drivers/rtc/rtc-ds1302.c:115:7: warning: Value stored to 'bp' during its initialization is never read drivers/rtc/rtc-ds1302.c:46:7: warning: Value stored to 'bp' during its initialization is never read Signed-off-by: Colin Ian King Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1302.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 0ec4be62322b..43bcb17c922e 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 */ @@ -112,7 +112,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 -- cgit v1.2.1 From 7b21db9184a21b3ba479030dcfecaf3f2fa94b1f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:15 +0100 Subject: rtc: documentation: correct nvmem date and version The nvmem interface appaeared in linux 4.13 Signed-off-by: Alexandre Belloni --- Documentation/ABI/testing/sysfs-class-rtc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-rtc b/Documentation/ABI/testing/sysfs-class-rtc index cf60412882f0..65270d95873c 100644 --- a/Documentation/ABI/testing/sysfs-class-rtc +++ b/Documentation/ABI/testing/sysfs-class-rtc @@ -58,8 +58,8 @@ Description: (RO) RTC-provided time in 24-hour notation (hh:mm:ss) What: /sys/class/rtc/rtcX/*/nvmem -Date: February 2016 -KernelVersion: 4.6 +Date: July 2017 +KernelVersion: 4.13 Contact: linux-rtc@vger.kernel.org Description: (RW) The non volatile storage exported as a raw file, as -- cgit v1.2.1 From 4cce9d3988ae33eb53742d9648ecc59046196e6f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:16 +0100 Subject: rtc: nvmem: pass nvmem_config to rtc_nvmem_register() To be able to remove nvmem_config from struct rtc_device, pass it as a parameter to rtc_nvmem_register. Signed-off-by: Alexandre Belloni --- drivers/rtc/class.c | 2 +- drivers/rtc/nvmem.c | 17 +++++++++-------- drivers/rtc/rtc-core.h | 6 ++++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 722d683e0b0f..47c4aeed5106 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -453,7 +453,7 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) rtc_proc_add_device(rtc); - rtc_nvmem_register(rtc); + rtc_nvmem_register(rtc, rtc->nvmem_config); rtc->registered = true; dev_info(rtc->dev.parent, "registered as %s\n", diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index 8567b4ed9ac6..0a3522bcdd25 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -46,7 +46,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 +64,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,20 +84,21 @@ static void rtc_nvram_unregister(struct rtc_device *rtc) /* * New ABI, uses nvmem */ -void rtc_nvmem_register(struct rtc_device *rtc) +void rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config) { - if (!rtc->nvmem_config) + if (!nvmem_config) return; - rtc->nvmem_config->dev = &rtc->dev; - rtc->nvmem_config->owner = rtc->owner; - rtc->nvmem = nvmem_register(rtc->nvmem_config); + nvmem_config->dev = &rtc->dev; + nvmem_config->owner = rtc->owner; + rtc->nvmem = nvmem_register(nvmem_config); if (IS_ERR_OR_NULL(rtc->nvmem)) return; /* Register the old ABI */ if (rtc->nvram_old_abi) - rtc_nvram_register(rtc); + rtc_nvram_register(rtc, nvmem_config->size); } void rtc_nvmem_unregister(struct rtc_device *rtc) diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 513b9bedd2c8..5f60e3b11cde 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h @@ -48,9 +48,11 @@ static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) #endif #ifdef CONFIG_RTC_NVMEM -void rtc_nvmem_register(struct rtc_device *rtc); +void rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config); void rtc_nvmem_unregister(struct rtc_device *rtc); #else -static inline void rtc_nvmem_register(struct rtc_device *rtc) {} +static inline void rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config) {} static inline void rtc_nvmem_unregister(struct rtc_device *rtc) {} #endif -- cgit v1.2.1 From 2cc8212198820487ec3fdcc7b98133701fc9dfc3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:17 +0100 Subject: rtc: nvmem: return error values In case of error, make rtc_nvmem_register() able to return an error value to its caller. Signed-off-by: Alexandre Belloni --- drivers/rtc/nvmem.c | 10 ++++++---- drivers/rtc/rtc-core.h | 11 +++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index 0a3522bcdd25..293df6db7c42 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -84,21 +84,23 @@ static void rtc_nvram_unregister(struct rtc_device *rtc) /* * New ABI, uses nvmem */ -void rtc_nvmem_register(struct rtc_device *rtc, - struct nvmem_config *nvmem_config) +int rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config) { if (!nvmem_config) - return; + return -ENODEV; nvmem_config->dev = &rtc->dev; 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, nvmem_config->size); + + return 0; } void rtc_nvmem_unregister(struct rtc_device *rtc) diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 5f60e3b11cde..05a67837fd76 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h @@ -48,11 +48,14 @@ static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) #endif #ifdef CONFIG_RTC_NVMEM -void rtc_nvmem_register(struct rtc_device *rtc, - struct nvmem_config *nvmem_config); +int rtc_nvmem_register(struct rtc_device *rtc, + struct nvmem_config *nvmem_config); void rtc_nvmem_unregister(struct rtc_device *rtc); #else -static inline void rtc_nvmem_register(struct rtc_device *rtc, - struct nvmem_config *nvmem_config) {} +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 -- cgit v1.2.1 From ab3ea36eda76069ba52e9b6aef5a9370b0b462bf Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:18 +0100 Subject: rtc: nvmem: disallow registering nvmem more than once Make rtc_nvmem_register return -EBUSY when an nvmem is already registered for that RTC. Signed-off-by: Alexandre Belloni --- drivers/rtc/nvmem.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index 293df6db7c42..fd1c39a5ade5 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -87,6 +87,9 @@ static void rtc_nvram_unregister(struct rtc_device *rtc) int rtc_nvmem_register(struct rtc_device *rtc, struct nvmem_config *nvmem_config) { + if (!IS_ERR_OR_NULL(rtc->nvmem)) + return -EBUSY; + if (!nvmem_config) return -ENODEV; -- cgit v1.2.1 From ac75779b72fd52741d7446ad27cf6d58c006c643 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 28 Feb 2018 21:58:02 +0100 Subject: rtc: nvmem: allow registering the nvmem device before the rtc Switch the parent of the nvmem device to the parent of the rtc device so it can be registered before the RTC. This is a small change in the ABI as the nvmem moves out of the /sys/class/rtc/rtcX folder to be under the parent device folder (that is where the previous nvram files where registered). However, it is still available under its correct location, /sys/bus/nvmem/devices which is the one that should be used by userspace applications. The other benefit is that the nvmem device can stay registered even if the rtc registration fails. Or it is possible to not register the rtc if the nvmem registration failed. Finally, it makes a lot of sense for devices that actually have different i2c or spi addresses for the RTC and the EEPROM. That is basically how it would end up when using MFD or even completely separate devices. Signed-off-by: Alexandre Belloni --- Documentation/ABI/testing/sysfs-class-rtc | 8 -------- drivers/rtc/class.c | 5 +++-- drivers/rtc/nvmem.c | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-class-rtc b/Documentation/ABI/testing/sysfs-class-rtc index 65270d95873c..792a38300336 100644 --- a/Documentation/ABI/testing/sysfs-class-rtc +++ b/Documentation/ABI/testing/sysfs-class-rtc @@ -57,14 +57,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: July 2017 -KernelVersion: 4.13 -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/drivers/rtc/class.c b/drivers/rtc/class.c index 47c4aeed5106..0cab397f6e37 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -293,8 +293,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 +310,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 +381,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 diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index fd1c39a5ade5..eb8c622cfcf4 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -93,7 +93,7 @@ int rtc_nvmem_register(struct rtc_device *rtc, if (!nvmem_config) return -ENODEV; - nvmem_config->dev = &rtc->dev; + nvmem_config->dev = rtc->dev.parent; nvmem_config->owner = rtc->owner; rtc->nvmem = nvmem_register(nvmem_config); if (IS_ERR_OR_NULL(rtc->nvmem)) -- cgit v1.2.1 From fd5cd21d995e67f87b3eb4adf938be85fe83ef4b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:19 +0100 Subject: rtc: export rtc_nvmem_register() to drivers Export rtc_nvmem_register() so it can be called from drivers instead of only the core. Signed-off-by: Alexandre Belloni --- drivers/rtc/nvmem.c | 3 +-- drivers/rtc/rtc-core.h | 13 ------------- include/linux/rtc.h | 13 +++++++++++++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/rtc/nvmem.c b/drivers/rtc/nvmem.c index eb8c622cfcf4..17ec4c8d0fad 100644 --- a/drivers/rtc/nvmem.c +++ b/drivers/rtc/nvmem.c @@ -14,8 +14,6 @@ #include #include -#include "rtc-core.h" - /* * Deprecated ABI compatibility, this should be removed at some point */ @@ -105,6 +103,7 @@ int rtc_nvmem_register(struct rtc_device *rtc, return 0; } +EXPORT_SYMBOL_GPL(rtc_nvmem_register); void rtc_nvmem_unregister(struct rtc_device *rtc) { diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 05a67837fd76..0abf98983e13 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h @@ -46,16 +46,3 @@ static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) return NULL; } #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 diff --git a/include/linux/rtc.h b/include/linux/rtc.h index fc6c90b57be0..fbc92fff7c2e 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -271,4 +271,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_ */ -- cgit v1.2.1 From 6910614f1e2806f43d0237a3566f83bfbee33440 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:20 +0100 Subject: rtc: ds1305: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1305.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index d8df2e9e14ad..affa90da26f1 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -703,15 +703,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 -- cgit v1.2.1 From eed9d7a335d67f8d61286fb3bbacce9c61c6dc52 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:21 +0100 Subject: rtc: ds1305: put ds1305_nvmem_cfg on the stack This makes to code safer on system using two similar RTCs. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1305.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index affa90da26f1..3d2400a39da9 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -544,15 +544,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 +557,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 -- cgit v1.2.1 From e9fb7682fa22b16175b6cabcc481ec53ba696c43 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:22 +0100 Subject: rtc: ds1307: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 923dde912f60..c146411a2099 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1696,6 +1696,11 @@ read_rtc: } } + ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops; + err = rtc_register_device(ds1307->rtc); + if (err) + return err; + if (chip->nvram_size) { ds1307->nvmem_cfg.name = "ds1307_nvram"; ds1307->nvmem_cfg.word_size = 1; @@ -1705,15 +1710,10 @@ read_rtc: 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; + rtc_nvmem_register(ds1307->rtc, &ds1307->nvmem_cfg); } - ds1307->rtc->ops = chip->rtc_ops ?: &ds13xx_rtc_ops; - err = rtc_register_device(ds1307->rtc); - if (err) - return err; - ds1307_hwmon_register(ds1307); ds1307_clks_register(ds1307); -- cgit v1.2.1 From 409baf1785db703583a5f0b51c0d0b114e14f4fb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:23 +0100 Subject: rtc: ds1307: put struct nvmem_config on the stack Avoid allocating memory for struct nvmem_config as it is only necessary at the nvmem registration. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index c146411a2099..4021d478b9f3 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 */ @@ -1702,16 +1701,18 @@ read_rtc: return err; 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; + 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, &ds1307->nvmem_cfg); + rtc_nvmem_register(ds1307->rtc, &nvmem_cfg); } ds1307_hwmon_register(ds1307); -- cgit v1.2.1 From 16fef391428e95b08e2c6ef9770f0d1185de770e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:24 +0100 Subject: rtc: ds1511: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1511.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 1e95312a6f2e..b1e51a4c2908 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -479,13 +479,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 -- cgit v1.2.1 From 71e19c5e25792db5f46d525eb5743186b148326d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:25 +0100 Subject: rtc: ds1511: put ds1511_nvmem_cfg on the stack Move ds1511_nvmem_cfg to the stack of ds1511_rtc_probe. This results in a very small code size reduction and make it safer on systems with two similar RTCs: text data bss dec hex filename 2128 164 4 2296 8f8 drivers/rtc/rtc-ds1511.o.before 2175 100 4 2279 8e7 drivers/rtc/rtc-ds1511.o.after Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1511.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index b1e51a4c2908..5f55214db9f8 100644 --- a/drivers/rtc/rtc-ds1511.c +++ b/drivers/rtc/rtc-ds1511.c @@ -422,20 +422,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,7 +478,6 @@ static int ds1511_rtc_probe(struct platform_device *pdev) pdata->rtc->ops = &ds1511_rtc_ops; - ds1511_nvmem_cfg.priv = &pdev->dev; pdata->rtc->nvram_old_abi = true; ret = rtc_register_device(pdata->rtc); -- cgit v1.2.1 From 3c1bb61fad370d7c440b8f81df76cbb4d52a9b6f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:26 +0100 Subject: rtc: m48t86: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t86.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index d9aea9b6d9cd..3a48a7eb3e9c 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -266,13 +266,14 @@ static int m48t86_rtc_probe(struct platform_device *pdev) 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", -- cgit v1.2.1 From e3f51c0d29164b2e4cf3c72c962f3a4891412e9b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:27 +0100 Subject: rtc: m48t86: put m48t86_nvmem_cfg on the stack Move m48t86_nvmem_cfg to the stack of m48t86_rtc_probe. This results in a very small code size reduction and make it safer on systems with two similar RTCs: text data bss dec hex filename 1733 164 0 1897 769 drivers/rtc/rtc-m48t86.o.before 1793 100 0 1893 765 drivers/rtc/rtc-m48t86.o.after Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t86.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 3a48a7eb3e9c..8d17be1e6650 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -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,8 +264,6 @@ 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->nvram_old_abi = true; err = rtc_register_device(info->rtc); -- cgit v1.2.1 From ce603842c282a68191022aa3361ae18fc50a7f82 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:28 +0100 Subject: rtc: omap: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-omap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 09ef802d6e54..e53cb27f4118 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -850,7 +850,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 +885,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: -- cgit v1.2.1 From 24849d177c63e3f9b2bd92eb5c17c7ee0da4d798 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:29 +0100 Subject: rtc: pcf85363: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85363.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index ea04e9f0930b..a1fe833d2431 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -164,6 +164,7 @@ static int pcf85363_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct pcf85363 *pcf85363; + int ret; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -193,10 +194,13 @@ static int pcf85363_probe(struct i2c_client *client, 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); + ret = rtc_register_device(pcf85363->rtc); + + rtc_nvmem_register(pcf85363->rtc, &pcf85363->nvmem_cfg); + + return ret; } static const struct of_device_id dev_ids[] = { -- cgit v1.2.1 From 0e7a412fa24c021cba7feebbc82878a44f58b33a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:30 +0100 Subject: rtc: pcf85363: put struct nvmem_config on the stack Avoid allocating memory for struct nvmem_config. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85363.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index a1fe833d2431..64573cccf7fe 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -80,7 +80,6 @@ static struct i2c_driver pcf85363_driver; struct pcf85363 { struct device *dev; struct rtc_device *rtc; - struct nvmem_config nvmem_cfg; struct regmap *regmap; }; @@ -164,6 +163,14 @@ 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)) @@ -187,18 +194,12 @@ 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->ops = &rtc_ops; ret = rtc_register_device(pcf85363->rtc); - rtc_nvmem_register(pcf85363->rtc, &pcf85363->nvmem_cfg); + nvmem_cfg.priv = pcf85363; + rtc_nvmem_register(pcf85363->rtc, &nvmem_cfg); return ret; } -- cgit v1.2.1 From 88d3aadea0c72bc9bfaec2504b331134056e9bce Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:31 +0100 Subject: rtc: rv8803: call rtc_nvmem_register() Call rtc_nvmem_register instead of letting the core do it and stop using the nvmem_config member of struct rtc_device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv8803.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index aae2576741a6..c10132d8cf2e 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -591,12 +591,13 @@ static int rv8803_probe(struct i2c_client *client, 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; + rtc_nvmem_register(rv8803->rtc, &rv8803->nvmem_cfg); + err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); if (err) return err; -- cgit v1.2.1 From c07fd9dea2fab9f4b1f246b766e124606cef187f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:32 +0100 Subject: rtc: rv8803: put struct nvmem_config on the stack Avoid allocating memory for struct nvmem_config. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv8803.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index c10132d8cf2e..6fb5041f750b 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,13 @@ 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->nvram_old_abi = true; err = rtc_register_device(rv8803->rtc); if (err) return err; - rtc_nvmem_register(rv8803->rtc, &rv8803->nvmem_cfg); + rtc_nvmem_register(rv8803->rtc, &nvmem_cfg); err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); if (err) -- cgit v1.2.1 From ce1ae8eb83bee42c5a0dbcc01346e41c6e85da43 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:33 +0100 Subject: rtc: rv8803: fix possible race condition The probe function is not allowed to fail after registering the RTC. Call rtc_register_device() at the end. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rv8803.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/rtc/rtc-rv8803.c b/drivers/rtc/rtc-rv8803.c index 6fb5041f750b..29fc3d210392 100644 --- a/drivers/rtc/rtc-rv8803.c +++ b/drivers/rtc/rtc-rv8803.c @@ -590,14 +590,6 @@ static int rv8803_probe(struct i2c_client *client, } } - 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); - err = rv8803_write_reg(rv8803->client, RV8803_EXT, RV8803_EXT_WADA); if (err) return err; @@ -608,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; -- cgit v1.2.1 From 0391df74a608e4e65c29ddf80e704edfa8f8ef25 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:34 +0100 Subject: rtc: remove nvmem_config Because nvmem_config is only used and copied at nvmem registration, remove it from struct rtc_device. All the rtc drivers using nvmem are now calling rtc_nvmem_register directly. Signed-off-by: Alexandre Belloni --- drivers/rtc/class.c | 2 -- include/linux/rtc.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 0cab397f6e37..5a5ab4fa14f9 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -454,8 +454,6 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) rtc_proc_add_device(rtc); - rtc_nvmem_register(rtc, rtc->nvmem_config); - rtc->registered = true; dev_info(rtc->dev.parent, "registered as %s\n", dev_name(&rtc->dev)); diff --git a/include/linux/rtc.h b/include/linux/rtc.h index fbc92fff7c2e..37b041f72f8d 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -145,7 +145,6 @@ struct rtc_device { bool registered; - struct nvmem_config *nvmem_config; struct nvmem_device *nvmem; /* Old ABI support */ bool nvram_old_abi; -- cgit v1.2.1 From b5086150a685dcf8a3a2943eb7677a5fc4186782 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:35 +0100 Subject: rtc: ds1343: simplify regmap initialization Avoid using memset as gcc can properly initialize structures. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1343.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 895fbeeb47fe..b5102cdd7f61 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -599,15 +599,11 @@ 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; - priv = devm_kzalloc(&spi->dev, sizeof(struct ds1343_priv), GFP_KERNEL); if (!priv) return -ENOMEM; -- cgit v1.2.1 From 1536f6dc9d3b9d265c0333970e3a52874144b10f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:36 +0100 Subject: rtc: ds1343: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1343.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index b5102cdd7f61..a5a5a363c6e1 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -642,12 +642,15 @@ 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->ops = &ds1343_rtc_ops; + + res = rtc_register_device(priv->rtc); + if (res) + return res; priv->irq = spi->irq; -- cgit v1.2.1 From ab392864039e7319d0be4f4fb4bbe20a8f8b544f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:37 +0100 Subject: rtc: ds1343: remove undocumented and useless sysfs files A documented ABI already exists to get information about the alarm. It is the only one that is used. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1343.c | 96 +----------------------------------------------- 1 file changed, 1 insertion(+), 95 deletions(-) diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index a5a5a363c6e1..67cae0dd8154 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -199,74 +199,6 @@ static struct bin_attribute nvram_attr = { .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 +245,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); @@ -325,26 +256,9 @@ static int ds1343_sysfs_register(struct device *dev) 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; - - device_remove_file(dev, &dev_attr_alarm_mode); - -error3: - device_remove_bin_file(dev, &nvram_attr); + return 0; -error2: device_remove_file(dev, &dev_attr_trickle_charger); error1: @@ -355,17 +269,9 @@ 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) -- cgit v1.2.1 From d7501f709410f6813e84ecd5a28e7dc8f47ff792 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:38 +0100 Subject: rtc: ds1343: use generic nvmem Instead of adding a binary sysfs attribute from the driver (which suffers from a race condition as the attribute appears after the device), use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1343.c | 66 +++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 67cae0dd8154..59d27db2fd37 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -153,52 +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; + struct ds1343_priv *ds1343 = priv; - ret = regmap_bulk_write(priv->map, address, buf, count); - if (ret < 0) - dev_err(&priv->spi->dev, "Error in nvram write %d", ret); - - 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); - - address = DS1343_NVRAM + off; + struct ds1343_priv *ds1343 = priv; - 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_tricklecharger(struct device *dev, struct device_attribute *attr, char *buf) { @@ -252,16 +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) return 0; - device_remove_file(dev, &dev_attr_trickle_charger); - -error1: device_remove_file(dev, &dev_attr_glitch_filter); return err; @@ -271,7 +234,6 @@ static void ds1343_sysfs_unregister(struct device *dev) { device_remove_file(dev, &dev_attr_glitch_filter); device_remove_file(dev, &dev_attr_trickle_charger); - device_remove_bin_file(dev, &nvram_attr); } static int ds1343_read_time(struct device *dev, struct rtc_time *dt) @@ -509,6 +471,14 @@ static int ds1343_probe(struct spi_device *spi) .write_flag_mask = 0x80, }; unsigned int data; int res; + 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) @@ -552,12 +522,16 @@ static int ds1343_probe(struct spi_device *spi) 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; if (priv->irq >= 0) { -- cgit v1.2.1 From affb842b84a27d12ab7fd0a86cefda0a343f0941 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:39 +0100 Subject: rtc: m48t59: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t59.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index d99a705bec07..e248e56ff8a1 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -480,11 +480,16 @@ 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->rtc->ops = ops; + + ret = rtc_register_device(m48t59->rtc); + if (ret) + return ret; + m48t59_nvram_attr.size = pdata->offset; ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); -- cgit v1.2.1 From 0ff3565d88cde06c4ce20c55e7ce23050e1d6a0d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:40 +0100 Subject: rtc: m48t59: use generic nvmem Instead of adding a binary sysfs attribute from the driver (which suffers from a race condition as the attribute appears after the device), use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t59.c | 56 +++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index e248e56ff8a1..d2ba7d76dbb9 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c @@ -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); @@ -484,27 +483,21 @@ static int m48t59_rtc_probe(struct platform_device *pdev) if (IS_ERR(m48t59->rtc)) return PTR_ERR(m48t59->rtc); + m48t59->rtc->nvram_old_abi = true; m48t59->rtc->ops = ops; - ret = rtc_register_device(m48t59->rtc); + nvmem_cfg.size = pdata->offset; + ret = rtc_nvmem_register(m48t59->rtc, &nvmem_cfg); if (ret) return ret; - m48t59_nvram_attr.size = pdata->offset; - - ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); + ret = rtc_register_device(m48t59->rtc); if (ret) return ret; return 0; } -static int m48t59_rtc_remove(struct platform_device *pdev) -{ - sysfs_remove_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); - return 0; -} - /* work with hotplug and coldplug */ MODULE_ALIAS("platform:rtc-m48t59"); @@ -513,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); -- cgit v1.2.1 From 11ad0b613d35f74dd8453d09b71dc2f0af7cf3e0 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:41 +0100 Subject: rtc: sirfsoc: remove useless sirfsoc_rtc_ioctl sirfsoc_rtc_ioctl() doesn't implement any actual ioctl, remove it. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sirfsoc.c | 18 ------------------ 1 file changed, 18 deletions(-) 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 }; -- cgit v1.2.1 From 18c88cc9b0483c78562a0192779ec4d7ddc5dcf5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:42 +0100 Subject: rtc: ds1553: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1553.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 9961ec646fd2..59eab5eceafa 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -308,11 +308,16 @@ 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; + + 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, -- cgit v1.2.1 From 3a9a06d44bf75a1e0752e2de686729fb2a85ad22 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:43 +0100 Subject: rtc: ds1553: use generic nvmem Instead of adding a binary sysfs attribute from the driver (which suffers from a race condition as the attribute appears after the device), use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1553.c | 55 +++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 59eab5eceafa..6205c28e0cdc 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -233,46 +233,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 +266,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) @@ -313,6 +308,7 @@ static int ds1553_rtc_probe(struct platform_device *pdev) 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) @@ -328,10 +324,8 @@ 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); + if (rtc_nvmem_register(pdata->rtc, &nvmem_cfg)) + dev_err(&pdev->dev, "unable to register nvmem\n"); return 0; } @@ -340,7 +334,6 @@ static int ds1553_rtc_remove(struct platform_device *pdev) { struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - sysfs_remove_bin_file(&pdev->dev.kobj, &ds1553_nvram_attr); if (pdata->irq > 0) writeb(0, pdata->ioaddr + RTC_INTERRUPTS); return 0; -- cgit v1.2.1 From 1af7068d2a19d333e9280f8a43bc7215c90bfb91 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:44 +0100 Subject: rtc: ds1553: make alarms useful Currently, the IRQs are disabled when the rtc driver is removed (e.g. when shutting down the platform). This means that the RTC will be unable to wakeup the platform. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1553.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 6205c28e0cdc..7334c824371a 100644 --- a/drivers/rtc/rtc-ds1553.c +++ b/drivers/rtc/rtc-ds1553.c @@ -330,21 +330,11 @@ static int ds1553_rtc_probe(struct platform_device *pdev) return 0; } -static int ds1553_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - if (pdata->irq > 0) - writeb(0, pdata->ioaddr + RTC_INTERRUPTS); - return 0; -} - /* work with hotplug and coldplug */ MODULE_ALIAS("platform:rtc-ds1553"); static struct platform_driver ds1553_rtc_driver = { .probe = ds1553_rtc_probe, - .remove = ds1553_rtc_remove, .driver = { .name = "rtc-ds1553", }, -- cgit v1.2.1 From 53d29e0a3afe0567db9e4360e8523b092eb2d4e4 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:45 +0100 Subject: rtc: cmos: fix possible race condition The probe function is not allowed to fail after registering the RTC because the following may happen: CPU0: CPU1: sys_load_module() do_init_module() do_one_initcall() cmos_do_probe() rtc_device_register() __register_chrdev() cdev->owner = struct module* open("/dev/rtc0") rtc_device_unregister() module_put() free_module() module_free(mod->module_core) /* struct module *module is now freed */ chrdev_open() spin_lock(cdev_lock) cdev_get() try_module_get() module_is_live() /* dereferences already freed struct module* */ Switch to devm_rtc_allocate_device/rtc_register_device to register the rtc as late as possible. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 9dca53df3584..e6393e784d0c 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -751,8 +751,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; @@ -822,6 +821,11 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) goto cleanup2; } + cmos_rtc.rtc->ops = &cmos_rtc_ops; + retval = rtc_register_device(cmos_rtc.rtc); + if (retval) + goto cleanup3; + 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" : @@ -833,12 +837,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) return 0; +cleanup3: + sysfs_remove_bin_file(&dev->kobj, &nvram); cleanup2: if (is_valid_irq(rtc_irq)) 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)); @@ -869,7 +874,6 @@ static void cmos_do_remove(struct device *dev) hpet_unregister_irq_handler(cmos_interrupt); } - rtc_device_unregister(cmos->rtc); cmos->rtc = NULL; ports = cmos->iomem; -- cgit v1.2.1 From 8b5b7958fd1cac54bdca62ec5552c6be0b38def4 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:46 +0100 Subject: rtc: cmos: use generic nvmem Instead of adding a binary sysfs attribute from the driver, use the core to register an nvmem device. This allows to use the in-kernel interface to access the nvram. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 73 +++++++++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index e6393e784d0c..b8ec6009171a 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) @@ -813,32 +806,28 @@ 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); - goto cleanup2; - } - cmos_rtc.rtc->ops = &cmos_rtc_ops; + cmos_rtc.rtc->nvram_old_abi = true; retval = rtc_register_device(cmos_rtc.rtc); if (retval) - goto cleanup3; + 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; -cleanup3: - sysfs_remove_bin_file(&dev->kobj, &nvram); cleanup2: if (is_valid_irq(rtc_irq)) free_irq(rtc_irq, cmos_rtc.rtc); @@ -867,8 +856,6 @@ 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); -- cgit v1.2.1 From 1358e7b2b3312372ba231f6c94902a8dbfc7d2db Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:47 +0100 Subject: rtc: ds1742: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1742.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 3abf1cbfb8ce..84e19fe2ca3b 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -196,11 +196,17 @@ 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); + rtc->ops = &ds1742_rtc_ops; + + ret = rtc_register_device(rtc); + if (ret) + return ret; + ret = sysfs_create_bin_file(&pdev->dev.kobj, &pdata->nvram_attr); if (ret) dev_err(&pdev->dev, "Unable to create sysfs entry: %s\n", -- cgit v1.2.1 From 87c78d9512cb85c286de5a8941eaeda8ca6f7bac Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:48 +0100 Subject: rtc: ds1742: use generic nvmem Instead of adding a binary sysfs attribute from the driver (which suffers from a race condition as the attribute appears after the device), use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1742.c | 67 +++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 41 deletions(-) diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c index 84e19fe2ca3b..52baf925a690 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) @@ -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; @@ -202,24 +197,15 @@ static int ds1742_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc); rtc->ops = &ds1742_rtc_ops; + rtc->nvram_old_abi = true; ret = rtc_register_device(rtc); if (ret) return ret; - 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); - - return 0; -} - -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; } @@ -231,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), -- cgit v1.2.1 From bcdd559268039d8340d38fa58668393596e29fdc Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:49 +0100 Subject: rtc: rp5c01: fix possible race condition The probe function is not allowed to fail after registering the RTC because the following may happen: CPU0: CPU1: sys_load_module() do_init_module() do_one_initcall() cmos_do_probe() rtc_device_register() __register_chrdev() cdev->owner = struct module* open("/dev/rtc0") rtc_device_unregister() module_put() free_module() module_free(mod->module_core) /* struct module *module is now freed */ chrdev_open() spin_lock(cdev_lock) cdev_get() try_module_get() module_is_live() /* dereferences already freed struct module* */ Switch to devm_rtc_allocate_device/rtc_register_device to register the rtc as late as possible. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rp5c01.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 026035373ae6..38a12435b5a0 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -249,16 +249,24 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) 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; + priv->rtc = rtc; error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); if (error) return error; + error = rtc_register_device(rtc); + if (error) { + sysfs_remove_bin_file(&dev->dev.kobj, &priv->nvram_attr); + return error; + } + return 0; } -- cgit v1.2.1 From 7335fb9be32409c43d81c806c14220d4fcb0227f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:50 +0100 Subject: rtc: rp5c01: use generic nvmem Instead of adding a binary sysfs attribute from the driver, use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rp5c01.c | 65 ++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 38a12435b5a0..043b1667b41a 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, @@ -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,13 +241,6 @@ 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); @@ -254,35 +250,22 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) 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; - error = rtc_register_device(rtc); - if (error) { - sysfs_remove_bin_file(&dev->dev.kobj, &priv->nvram_attr); - 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); -- cgit v1.2.1 From 8f21092d65fd83e7a227c3aa88b79b3ec33a9b6e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:51 +0100 Subject: rtc: stk17ta8: make alarms useful Currently, the IRQs are disabled when the rtc driver is removed (e.g. when shutting down the platform). This means that the RTC will be unable to wakeup the platform. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stk17ta8.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index a456cb6177ea..39a80491e567 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -340,11 +340,8 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) 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; } -- cgit v1.2.1 From 91cb6774f6355eff527544181d2bfad1b7d054cf Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:52 +0100 Subject: rtc: stk17ta8: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stk17ta8.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 39a80491e567..f936accf622f 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -328,11 +328,16 @@ 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); + pdata->rtc->ops = &stk17ta8_rtc_ops; + + ret = rtc_register_device(pdata->rtc); + if (ret) + return ret; + ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); return ret; -- cgit v1.2.1 From 8d3e6b55cedaeadd1216d4b548f346c169099f1f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:53 +0100 Subject: rtc: stk17ta8: fix possible race condition The probe function is not allowed to fail after registering the RTC. Call rtc_register_device() at the end. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stk17ta8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index f936accf622f..1d6febbe7d39 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -334,11 +334,11 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) pdata->rtc->ops = &stk17ta8_rtc_ops; - ret = rtc_register_device(pdata->rtc); + ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); if (ret) return ret; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); + ret = rtc_register_device(pdata->rtc); return ret; } -- cgit v1.2.1 From d7ca4299d7c035969652596f0daa76407f6cfbdd Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:54 +0100 Subject: rtc: stk17ta8: use generic nvmem Instead of adding a binary sysfs attribute from the driver, use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stk17ta8.c | 64 +++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 1d6febbe7d39..01a3bef77aa5 100644 --- a/drivers/rtc/rtc-stk17ta8.c +++ b/drivers/rtc/rtc-stk17ta8.c @@ -242,46 +242,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 +274,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) @@ -333,21 +325,14 @@ static int stk17ta8_rtc_probe(struct platform_device *pdev) return PTR_ERR(pdata->rtc); pdata->rtc->ops = &stk17ta8_rtc_ops; + pdata->rtc->nvram_old_abi = true; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); + nvmem_cfg.priv = pdata; + ret = rtc_nvmem_register(pdata->rtc, &nvmem_cfg); if (ret) return ret; - ret = rtc_register_device(pdata->rtc); - - return ret; -} - -static int stk17ta8_rtc_remove(struct platform_device *pdev) -{ - sysfs_remove_bin_file(&pdev->dev.kobj, &stk17ta8_nvram_attr); - - return 0; + return rtc_register_device(pdata->rtc); } /* work with hotplug and coldplug */ @@ -355,7 +340,6 @@ MODULE_ALIAS("platform:stk17ta8"); static struct platform_driver stk17ta8_rtc_driver = { .probe = stk17ta8_rtc_probe, - .remove = stk17ta8_rtc_remove, .driver = { .name = "stk17ta8", }, -- cgit v1.2.1 From a0151062ead35b3cc100a2b99b5c87b700ee52c0 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:55 +0100 Subject: rtc: tx4939: remove arch/mips dependency Copy RTC definitions from arch/mips/include/asm/txx9/tx4939.h to the RTC driver so it doesn't depend on arch/mips anymore. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tx4939.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 560d9a5e0225..1f4013d8ae7b 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -14,7 +14,30 @@ #include #include #include -#include + +#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; -- cgit v1.2.1 From faec5f7bcca3a2e81aa7bd8412b22e808df508c3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:56 +0100 Subject: rtc: tx4939: extend test coverage The rtc-tx4939 driver now compiles correctly on other architectures, add COMPILE_TEST to improve code coverage. Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 8ab5f0a5d323..f6d7e490e714 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1512,7 +1512,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. -- cgit v1.2.1 From 68981fd1515de16f8effdd39e81f9a6084a895f7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:57 +0100 Subject: rtc: tx4939: switch to rtc_register_device This allows for future improvement of the driver. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tx4939.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 1f4013d8ae7b..75c3887fbc6c 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -283,10 +283,16 @@ 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; + + ret = rtc_register_device(rtc); + if (ret) + return ret; + pdata->rtc = rtc; ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); -- cgit v1.2.1 From a2fa9b8e5abc7d16d5617996638f796fbd61cbb2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:58 +0100 Subject: rtc: tx4939: fix possible race condition The probe function is not allowed to fail after registering the RTC. Call rtc_register_device() at the end. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tx4939.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 75c3887fbc6c..5a3a6b457b8f 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -289,12 +289,13 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev) rtc->ops = &tx4939_rtc_ops; - ret = rtc_register_device(rtc); + ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); if (ret) return ret; pdata->rtc = rtc; - ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); + + ret = rtc_register_device(rtc); return ret; } -- cgit v1.2.1 From dd888c61c9d4ef54d5a9884226989e3cceaacbd3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Feb 2018 23:47:59 +0100 Subject: rtc: tx4939: use generic nvmem Instead of adding a binary sysfs attribute from the driver, use the core to register an nvmem device. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tx4939.c | 59 +++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index 5a3a6b457b8f..fcf837d50b70 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -212,58 +212,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) @@ -288,23 +282,22 @@ static int __init tx4939_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc); rtc->ops = &tx4939_rtc_ops; - - ret = sysfs_create_bin_file(&pdev->dev.kobj, &tx4939_rtc_nvram_attr); - if (ret) - return ret; + rtc->nvram_old_abi = true; pdata->rtc = rtc; - ret = rtc_register_device(rtc); + nvmem_cfg.priv = pdata; + ret = rtc_nvmem_register(rtc, &nvmem_cfg); + if (ret) + return 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); -- cgit v1.2.1 From 5b9fc795f90c0c509a24ba1f64d0d960f09e40da Mon Sep 17 00:00:00 2001 From: Denis Osterland Date: Tue, 23 Jan 2018 13:17:58 +0100 Subject: rtc: isl1208: Fix unintended clear of SR bits After successful sr = isl1208_i2c_set_regs(client, 0, regs, ISL1208_RTC_SECTION_LEN); sr will be 0. As a result sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr & ~ISL1208_REG_SR_WRTC); is equal to sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, 0); which clears all flags in SR. Add an additional read of SR, to have value of SR in sr again. Signed-off-by: Denis Osterland Signed-off-by: Michael Grzeschik Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl1208.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 8dd299c6a1f3..c8b495348229 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) { -- cgit v1.2.1 From 588519ff16552c5a6f6a189767692db6689cadad Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 12 Feb 2018 00:38:46 -0200 Subject: rtc: mxc_v2: Fix _iomem pointer notation Fix the iomem pointer notation in order to fix the following sparse warnings: drivers/rtc/rtc-mxc_v2.c:280:18: warning: incorrect type in argument 1 (different address spaces) drivers/rtc/rtc-mxc_v2.c:280:18: expected void const volatile [noderef] *addr drivers/rtc/rtc-mxc_v2.c:280:18: got void *[noderef] ioaddr drivers/rtc/rtc-mxc_v2.c:329:44: warning: incorrect type in argument 1 (different address spaces) drivers/rtc/rtc-mxc_v2.c:329:44: expected void *[noderef] ioaddr drivers/rtc/rtc-mxc_v2.c:329:44: got void [noderef] * drivers/rtc/rtc-mxc_v2.c:339:44: warning: incorrect type in argument 1 (different address spaces) drivers/rtc/rtc-mxc_v2.c:339:44: expected void *[noderef] ioaddr drivers/rtc/rtc-mxc_v2.c:339:44: got void [noderef] * Signed-off-by: Fabio Estevam Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mxc_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; -- cgit v1.2.1 From 9e7002a70e4294a093b3cacf2346af33aeefd265 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 6 Feb 2018 23:12:26 +0100 Subject: char: rtc: remove unused rtc_control() API Since commit 34ce71a96dcb ("ALSA: timer: remove legacy rtctimer"), the rtc_register/rtc_control/rtc_unregister API is unused. As it is highly unlikely to be needed again, remove it. Acked-by: Greg Kroah-Hartman Acked-by: Arnd Bergmann Signed-off-by: Alexandre Belloni --- drivers/char/rtc.c | 83 ----------------------------------------------------- include/linux/rtc.h | 4 --- 2 files changed, 87 deletions(-) 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/include/linux/rtc.h b/include/linux/rtc.h index 37b041f72f8d..3b65b201169c 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -211,10 +211,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); -- cgit v1.2.1 From e6a0b0f4085c9a56fa50c9666ee662d197c4707d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 16 Feb 2018 11:06:00 +0100 Subject: MAINTAINERS: rtc: update my email address Free Electrons is now Bootlin. Signed-off-by: Alexandre Belloni --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..5c676c3c990f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11693,7 +11693,7 @@ X: kernel/torture.c REAL TIME CLOCK (RTC) SUBSYSTEM M: Alessandro Zummo -M: Alexandre Belloni +M: Alexandre Belloni 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 -- cgit v1.2.1 From 347876ad47b9923ce26e686173bbf46581802ffa Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 15 Feb 2018 19:36:14 +0000 Subject: rtc: tx4939: avoid unintended sign extension on a 24 bit shift The shifting of buf[5] by 24 bits to the left will be promoted to a 32 bit signed int and then sign-extended to an unsigned long. If the top bit of buf[5] is set then all then all the upper bits sec end up as also being set because of the sign-extension. Fix this by casting buf[5] to an unsigned long before the shift. Detected by CoverityScan, CID#1465292 ("Unintended sign extension") Fixes: 0e1492330cd2 ("rtc: add rtc-tx4939 driver") Signed-off-by: Colin Ian King Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tx4939.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-tx4939.c b/drivers/rtc/rtc-tx4939.c index fcf837d50b70..3b83cdb0b828 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -109,7 +109,8 @@ 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); } @@ -170,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); } -- cgit v1.2.1 From 1c90d9f1c80ba28ddb61c3dbdc55ac686c073d75 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 20 Feb 2018 22:05:29 +0100 Subject: rtc: ds1511: let the core handle invalid time Returning a valid time when the time is invalid is a bad practice, because then userspace is not able to react on the information. Also, it doesn't make sense to return epoch because it is already the default time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1511.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c index 5f55214db9f8..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; } -- cgit v1.2.1 From 7d1bd37ff06b9e7c49dc033fce4069f69ad6e564 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 20 Feb 2018 23:43:09 +0100 Subject: rtc: ds1553: let the core handle invalid time Returning a valid time when the time is invalid is a bad practice, because then userspace is not able to react on the information. Also, it doesn't make sense to return epoch because it is already the default time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1553.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c index 7334c824371a..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; } -- cgit v1.2.1 From 812318a094d0715194d9f686b22ee67e7dc59d93 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:44:26 +0100 Subject: rtc: cmos: let the core handle invalid time Setting the rtc to a valid time when the time is invalid is a bad practice, because then userspace doesn't know it shouldn't trust the RTC. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b8ec6009171a..d98ad4874d8b 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -1262,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) @@ -1276,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) {} -- cgit v1.2.1 From bff11e3aa9ccfce1a66ef05871d01c1da533f896 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:20:43 +0100 Subject: rtc: rs5c348: let the core handle invalid time Returning a valid time when the time is invalid is a bad practice, because then userspace is not able to react on the information. Also, it doesn't make sense to return epoch because it is already the default time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rs5c348.c | 5 ----- 1 file changed, 5 deletions(-) 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; } -- cgit v1.2.1 From bd7f4e7598921506c2ae343954fdbb764840921b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 18 Feb 2018 23:36:18 +0100 Subject: rtc: stk17ta8: let the core handle invalid time Returning a valid time when the time is invalid is a bad practice, because then userspace is not able to react on the information. Also, it doesn't make sense to return epoch because it is already the default time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-stk17ta8.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c index 01a3bef77aa5..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; } -- cgit v1.2.1 From 146d21bd9dc167d75bed4c0fdfe790db7565e99b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:23:55 +0100 Subject: rtc: stop validating rtc_time after rtc_time64_to_tm rtc_time64_to_tm never generates an invalid tm. It is not necessary to validate it. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ab3100.c | 2 +- drivers/rtc/rtc-mc13xxx.c | 2 +- drivers/rtc/rtc-zynqmp.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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-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-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) -- cgit v1.2.1 From ab62670e57174c547abbecacf6df78d3dcf03f26 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:23:55 +0100 Subject: rtc: stop validating rtc_time after rtc_time_to_tm rtc_time_to_tm never generates an invalid tm. It is not necessary to validate it. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ab8500.c | 2 +- drivers/rtc/rtc-coh901331.c | 2 +- drivers/rtc/rtc-jz4740.c | 2 +- drivers/rtc/rtc-lpc32xx.c | 2 +- drivers/rtc/rtc-ls1x.c | 2 +- drivers/rtc/rtc-mpc5121.c | 2 +- drivers/rtc/rtc-pcap.c | 2 +- drivers/rtc/rtc-ps3.c | 2 +- drivers/rtc/rtc-starfire.c | 2 +- drivers/rtc/rtc-tps6586x.c | 2 +- drivers/rtc/rtc-tx4939.c | 2 +- drivers/rtc/rtc-wm831x.c | 2 +- drivers/rtc/rtc-xgene.c | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 24a0af650a1b..98c7123cd7ba 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -131,7 +131,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) 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-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-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-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-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-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-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-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 3b83cdb0b828..08dbefc79520 100644 --- a/drivers/rtc/rtc-tx4939.c +++ b/drivers/rtc/rtc-tx4939.c @@ -112,7 +112,7 @@ static int tx4939_rtc_read_time(struct device *dev, struct rtc_time *tm) 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) 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) -- cgit v1.2.1 From 4d894685f97fea327d375bb28058b22199d65ef5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:23:56 +0100 Subject: rtc: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ac100.c | 2 +- drivers/rtc/rtc-au1xxx.c | 2 +- drivers/rtc/rtc-bq32k.c | 2 +- drivers/rtc/rtc-da9052.c | 3 +-- drivers/rtc/rtc-da9055.c | 2 +- drivers/rtc/rtc-da9063.c | 2 +- drivers/rtc/rtc-ds1216.c | 2 +- drivers/rtc/rtc-ds1286.c | 2 +- drivers/rtc/rtc-ds1302.c | 3 +-- drivers/rtc/rtc-ds1305.c | 3 +-- drivers/rtc/rtc-ds1307.c | 3 +-- drivers/rtc/rtc-ds1343.c | 2 +- drivers/rtc/rtc-ds1347.c | 2 +- drivers/rtc/rtc-ds1390.c | 2 +- drivers/rtc/rtc-ds1685.c | 2 +- drivers/rtc/rtc-ds1742.c | 2 +- drivers/rtc/rtc-ds2404.c | 2 +- drivers/rtc/rtc-ds3232.c | 2 +- drivers/rtc/rtc-efi.c | 2 +- drivers/rtc/rtc-fm3130.c | 3 +-- drivers/rtc/rtc-isl12022.c | 2 +- drivers/rtc/rtc-lpc24xx.c | 2 +- drivers/rtc/rtc-m41t80.c | 2 +- drivers/rtc/rtc-m41t94.c | 3 +-- drivers/rtc/rtc-m48t35.c | 2 +- drivers/rtc/rtc-m48t59.c | 2 +- drivers/rtc/rtc-m48t86.c | 2 +- drivers/rtc/rtc-max6902.c | 2 +- drivers/rtc/rtc-max6916.c | 2 +- drivers/rtc/rtc-max8997.c | 2 +- drivers/rtc/rtc-max8998.c | 2 +- drivers/rtc/rtc-mcp795.c | 2 +- drivers/rtc/rtc-mrst.c | 2 +- drivers/rtc/rtc-msm6242.c | 2 +- drivers/rtc/rtc-mt7622.c | 2 +- drivers/rtc/rtc-mv.c | 2 +- drivers/rtc/rtc-pcf2123.c | 2 +- drivers/rtc/rtc-pcf2127.c | 2 +- drivers/rtc/rtc-pcf50633.c | 2 +- drivers/rtc/rtc-pcf8523.c | 2 +- drivers/rtc/rtc-pic32.c | 2 +- drivers/rtc/rtc-r9701.c | 2 +- drivers/rtc/rtc-rp5c01.c | 2 +- drivers/rtc/rtc-rx6110.c | 2 +- drivers/rtc/rtc-rx8010.c | 2 +- drivers/rtc/rtc-rx8025.c | 2 +- drivers/rtc/rtc-s3c.c | 2 +- drivers/rtc/rtc-s5m.c | 2 +- drivers/rtc/rtc-sh.c | 2 +- drivers/rtc/rtc-sun6i.c | 2 +- drivers/rtc/rtc-sunxi.c | 2 +- 51 files changed, 51 insertions(+), 57 deletions(-) diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 8ff9dc3fe5bf..080e3c04be43 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -387,7 +387,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-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..e8698e9870fe 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -110,7 +110,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-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 43bcb17c922e..2a881150d51c 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -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 = { diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 3d2400a39da9..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) diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4021d478b9f3..a13e59edff53 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -437,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) diff --git a/drivers/rtc/rtc-ds1343.c b/drivers/rtc/rtc-ds1343.c index 59d27db2fd37..5208da4cf94a 100644 --- a/drivers/rtc/rtc-ds1343.c +++ b/drivers/rtc/rtc-ds1343.c @@ -254,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) 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-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 52baf925a690..2d781180e968 100644 --- a/drivers/rtc/rtc-ds1742.c +++ b/drivers/rtc/rtc-ds1742.c @@ -112,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 = { 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-isl12022.c b/drivers/rtc/rtc-isl12022.c index 38586a024ee8..46093cd13d5e 100644 --- a/drivers/rtc/rtc-isl12022.c +++ b/drivers/rtc/rtc-isl12022.c @@ -149,7 +149,7 @@ 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) 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-m41t80.c b/drivers/rtc/rtc-m41t80.c index c90fba3ed861..1103cdc33bfa 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -230,7 +230,7 @@ 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. */ 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 d2ba7d76dbb9..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) diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 8d17be1e6650..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) 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-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-mcp795.c b/drivers/rtc/rtc-mcp795.c index 77f21331ae21..79e24eadbe99 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c @@ -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-mrst.c b/drivers/rtc/rtc-mrst.c index 7334c44fa7c3..901a8d170f68 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) 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..da213278f343 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) diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 79bb28617d45..944c5c0fadd0 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) 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-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-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-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-rp5c01.c b/drivers/rtc/rtc-rp5c01.c index 043b1667b41a..f1c160fe7d37 100644 --- a/drivers/rtc/rtc-rp5c01.c +++ b/drivers/rtc/rtc-rp5c01.c @@ -115,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) 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-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..6deae10c14ac 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c @@ -407,7 +407,7 @@ 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) 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-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) -- cgit v1.2.1 From 27d29503ed231df4d2c2b4ffb58f121af72c2bd9 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:23:54 +0100 Subject: rtc: ab-b5ze-s3: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ab-b5ze-s3.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c index a319bf1e49de..e55f35fa0b58 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; } -- cgit v1.2.1 From 0e1ed55b86b329f0705596c378ebd771214ed122 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:27:10 +0100 Subject: rtc: nuc900: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-nuc900.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) 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) -- cgit v1.2.1 From 27d1f54e53e9de1f2b4885c9f85975ed63e3c39d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:18:23 +0100 Subject: rtc: r7301: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-r7301.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) -- cgit v1.2.1 From 7157cdb3dbdeba7934c7402e22643e6371d26266 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:24:19 +0100 Subject: rtc: sc27xx: stop validating rtc_time in .read_time rtc_time64_to_tm never generates an invalid tm. It is not necessary to validate it. Also, the RTC core is always calling rtc_valid_tm after the read_time callback. Reviewed-by: Baolin Wang Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sc27xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) -- cgit v1.2.1 From 51f13ac79d247453506886e90391c011bf72eb74 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 19 Feb 2018 16:23:57 +0100 Subject: rtc: cpcap: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Reviewed-by: Sebastian Reichel Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cpcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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) -- cgit v1.2.1 From 19952b649d37ca5e083cffcfdf9f6dc1b11df769 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 20 Feb 2018 23:55:40 +0100 Subject: rtc: isl12022: remove useless indirection isl12022_get_datetime and isl12022_set_datetime are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-isl12022.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-isl12022.c b/drivers/rtc/rtc-isl12022.c index 46093cd13d5e..fa5c15d45070 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; @@ -152,8 +153,9 @@ static int isl12022_get_datetime(struct i2c_client *client, struct rtc_time *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; @@ -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, -- cgit v1.2.1 From a4a61e3d8fc9859b37874ece81d6bb18f70fb3e3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:02:08 +0100 Subject: rtc: m41t93: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t93.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; } -- cgit v1.2.1 From 25e297c91a1198e70b6a9588a813a1ef43b2bd02 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:05:20 +0100 Subject: rtc: max77686: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it just before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-max77686.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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) -- cgit v1.2.1 From 93d2631308b0c164e165d538769d45051dcdb0a0 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:33:37 +0100 Subject: rtc: omap: stop validating rtc_time in .set_time and .set_alarm The RTC core is always validating the rtc_time struct before calling .set_time or .set_alarm. It is not necessary to do it again. Also, rtc_time_to_tm never generates an invalid rtc_tm (it can be out of range though). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-omap.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index e53cb27f4118..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); -- cgit v1.2.1 From 88207816231d0fbf5c31d686bebd566b0039b954 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:23:19 +0100 Subject: rtc: spear: stop validating rtc_time in .set_time and .set_alarm The RTC core is always validating the rtc_time struct before calling .set_time or .set_alarm. It is not necessary to do it again. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-spear.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) 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); -- cgit v1.2.1 From e08f40d0a5a4c000f87cff96a4b7131f1f2346e0 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:03:49 +0100 Subject: rtc: tegra: stop validating rtc_time in .set_time The RTC core is always validating the rtc_time struct before calling .set_time. It is not necessary to do it again in .set_time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tegra.c | 4 ---- 1 file changed, 4 deletions(-) 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", -- cgit v1.2.1 From 3df0ad5da99c8f47a5ce886ff7d7fdf200b415de Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 20 Feb 2018 23:42:27 +0100 Subject: rtc: abx80x: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-abx80x.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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) -- cgit v1.2.1 From f0b658027fdb092e79b9164c09926b4215e99a4c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:10:41 +0100 Subject: rtc: pm8xxx: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index fac835530671..8e0128796824 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -190,12 +190,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); -- cgit v1.2.1 From 21fbc16abe1dc4c10a0cdc7a2a9a00155f7cfec5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:23:31 +0100 Subject: rtc: rx4581: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rx4581.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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) -- cgit v1.2.1 From 49b9c0921d15618952c3fb8fc91f8b834f1cddef Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 00:25:18 +0100 Subject: rtc: rx8581: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rx8581.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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) -- cgit v1.2.1 From 8d39f72edd0c818274f6a8d3dcf3d199d644d7fc Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 18 Feb 2018 23:43:07 +0100 Subject: rtc: tile: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-tile.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/rtc/rtc-tile.c b/drivers/rtc/rtc-tile.c index 0b60867d8390..ef1cdabf05b4 100644 --- a/drivers/rtc/rtc-tile.c +++ b/drivers/rtc/rtc-tile.c @@ -39,9 +39,6 @@ static int read_rtc_time(struct device *dev, struct rtc_time *tm) tm->tm_yday = 0; tm->tm_isdst = 0; - if (rtc_valid_tm(tm) < 0) - dev_warn(dev, "Read invalid date/time from RTC\n"); - return 0; } -- cgit v1.2.1 From 108f71c9592579ea402e303a386e70e8dad17f93 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:48:46 +0100 Subject: rtc: rk808: remove useless debug message At probe time, printing a message when the time is invalid doesn't have much value. Also, as the comment suggest, this is a leftover from development wherhe this was used to set the RTc to a default time. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rk808.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index 35c9aada07c8..e40f35d1ced3 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,16 +403,6 @@ 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", -- cgit v1.2.1 From d448165e53bc5f01e813d3554f6da42b17d48f3b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 11:57:05 +0100 Subject: rtc: rk808: fix possible race condition The probe function is not allowed to fail after registering the RTC because the following may happen: CPU0: CPU1: sys_load_module() do_init_module() do_one_initcall() cmos_do_probe() rtc_device_register() __register_chrdev() cdev->owner = struct module* open("/dev/rtc0") rtc_device_unregister() module_put() free_module() module_free(mod->module_core) /* struct module *module is now freed */ chrdev_open() spin_lock(cdev_lock) cdev_get() try_module_get() module_is_live() /* dereferences already freed struct module* */ Switch to devm_rtc_allocate_device/rtc_register_device to register the rtc as late as possible. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rk808.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-rk808.c b/drivers/rtc/rtc-rk808.c index e40f35d1ced3..739c0d42e835 100644 --- a/drivers/rtc/rtc-rk808.c +++ b/drivers/rtc/rtc-rk808.c @@ -405,12 +405,11 @@ static int rk808_rtc_probe(struct platform_device *pdev) 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) { @@ -427,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 = { -- cgit v1.2.1 From 95690459df73f6f0ac3fe58adf62eae702d21c6e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 13:52:35 +0100 Subject: rtc: s35390a: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 7067bca5c20d..604f527a1235 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -450,7 +450,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 +507,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, -- cgit v1.2.1 From cbec4ad1220ae75bd22f34e556c9d4c6acd276d1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 13:54:46 +0100 Subject: rtc: s35390a: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 604f527a1235..18c1d8a9f447 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -271,7 +271,7 @@ 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) -- cgit v1.2.1 From b84f35de4c4ee7930b8abab5f820aaf3d1518dda Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 14:00:18 +0100 Subject: rtc: s35390a: remove useless indirection s35390a_set_datetime, s35390a_get_datetime, s35390a_set_alarm and s35390a_read_alarm are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-s35390a.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 18c1d8a9f447..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; @@ -274,8 +276,9 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *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) { -- cgit v1.2.1 From abf262506b94aa24d8daccd957fd749f4720cbe6 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 15:42:32 +0100 Subject: rtc: rs5c372: remove useless message It is not necessary to print a message when the time is invalid as userspace will already get an error (and an optional dev_dbg message). Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rs5c372.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index d4eff8d7131f..37aa78fd2c4d 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -581,7 +581,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 +661,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; -- cgit v1.2.1 From 4f2c178f0c894a4a49f2086d7a90262ac0472069 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 15:43:53 +0100 Subject: rtc: rs5c372: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rs5c372.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 37aa78fd2c4d..ae7fa4324b0a 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c @@ -234,8 +234,7 @@ 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) -- cgit v1.2.1 From b05e79bd586f262c371479df645a5826e1e8eeeb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 15:47:14 +0100 Subject: rtc: rs5c372: remove useless indirection rs5c372_get_datetime and rs5c372_set_datetime are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-rs5c372.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index ae7fa4324b0a..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); @@ -237,8 +238,9 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *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; @@ -304,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); -- cgit v1.2.1 From ca74940ee6775754af026f6405f494860f518bf9 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 16:01:52 +0100 Subject: rtc: max6900: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-max6900.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index cbdc86a560ba..84f06106f5ba 100644 --- a/drivers/rtc/rtc-max6900.c +++ b/drivers/rtc/rtc-max6900.c @@ -157,7 +157,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) -- cgit v1.2.1 From 7407da4e1e17110c08ece439dbc328d4efc756e2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 16:04:27 +0100 Subject: rtc: max6900: remove useless indirection max6900_i2c_read_time and max6900_i2c_set_time are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-max6900.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c index 84f06106f5ba..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]; @@ -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, -- cgit v1.2.1 From eed1bfcd1fc3b340e888491cd513e8b058b4fb39 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 16:07:34 +0100 Subject: rtc: pcf85063: stop validating rtc_time in .read_time The RTC core is always calling rtc_valid_tm after the read_time callback. It is not necessary to call it before returning from the callback. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85063.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index a06dff994c83..6ad4511d7ee1 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -114,7 +114,7 @@ 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) -- cgit v1.2.1 From 26fb93c27a73b28d2665bd470118850e27ff7704 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 21 Feb 2018 16:09:27 +0100 Subject: rtc: pcf85063: remove useless indirection pcf85063_get_datetime and pcf85063_set_datetime are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85063.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 6ad4511d7ee1..3558433e8787 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -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]; @@ -117,8 +118,9 @@ static int pcf85063_get_datetime(struct i2c_client *client, struct rtc_time *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 -- cgit v1.2.1 From e169f8860f105438bca76445be2cee32889138f4 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 9 Feb 2018 19:05:34 +0100 Subject: rtc: m41t80: move m41t80_rtc_mutex to the block where it is used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without CONFIG_RTC_DRV_M41T80_WDT the compiler complains: |drivers/rtc/rtc-m41t80.c:76 ‘m41t80_rtc_mutex’ defined but not used [-Wunused-variable] Move the variable to the block where it is used. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 1103cdc33bfa..b3e33320c0bf 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 }, @@ -598,6 +597,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 */ -- cgit v1.2.1 From acaec38a6f32a91afb415df049c2f1a7fe10e85b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 25 Feb 2018 21:14:31 +0100 Subject: rtc: m41t80: fix race conditions The IRQ is requested before the struct rtc is allocated and registered, but this struct is used in the IRQ handler, leading to: Unable to handle kernel NULL pointer dereference at virtual address 0000017c pgd = a38a2f9b [0000017c] *pgd=00000000 Internal error: Oops: 5 [#1] ARM Modules linked in: CPU: 0 PID: 613 Comm: irq/48-m41t80 Not tainted 4.16.0-rc1+ #42 Hardware name: Atmel SAMA5 PC is at mutex_lock+0x14/0x38 LR is at m41t80_handle_irq+0x1c/0x9c pc : [] lr : [] psr: 20000013 sp : dec73f30 ip : 00000000 fp : dec56d98 r10: df437cf0 r9 : c0a03008 r8 : c0145ffc r7 : df5c4300 r6 : dec568d0 r5 : df593000 r4 : 0000017c r3 : df592800 r2 : 60000013 r1 : df593000 r0 : 0000017c Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c53c7d Table: 20004059 DAC: 00000051 Process irq/48-m41t80 (pid: 613, stack limit = 0xb52d091e) Stack: (0xdec73f30 to 0xdec74000) 3f20: dec56840 df5c4300 00000001 df5c4300 3f40: c0145ffc c0146018 dec56840 ffffe000 00000001 c0146290 dec567c0 00000000 3f60: c0146084 ed7c9a62 c014615c dec56d80 dec567c0 00000000 dec72000 dec56840 3f80: c014615c c012ffc0 dec72000 dec567c0 c012fe80 00000000 00000000 00000000 3fa0: 00000000 00000000 00000000 c01010e8 00000000 00000000 00000000 00000000 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 29282726 2d2c2b2a [] (mutex_lock) from [] (m41t80_handle_irq+0x1c/0x9c) [] (m41t80_handle_irq) from [] (irq_thread_fn+0x1c/0x54) [] (irq_thread_fn) from [] (irq_thread+0x134/0x1c0) [] (irq_thread) from [] (kthread+0x140/0x148) [] (kthread) from [] (ret_from_fork+0x14/0x2c) Exception stack(0xdec73fb0 to 0xdec73ff8) 3fa0: 00000000 00000000 00000000 00000000 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000 Code: e3c33d7f e3c3303f f5d0f000 e593300c (e1901f9f) ---[ end trace 22b027302eb7c604 ]--- genirq: exiting task "irq/48-m41t80" (613) is an active IRQ thread (irq 48) Also, there is another possible race condition. The probe function is not allowed to fail after the RTC is registered because the following may happen: CPU0: CPU1: sys_load_module() do_init_module() do_one_initcall() cmos_do_probe() rtc_device_register() __register_chrdev() cdev->owner = struct module* open("/dev/rtc0") rtc_device_unregister() module_put() free_module() module_free(mod->module_core) /* struct module *module is now freed */ chrdev_open() spin_lock(cdev_lock) cdev_get() try_module_get() module_is_live() /* dereferences already freed struct module* */ Switch to devm_rtc_allocate_device/rtc_register_device to allocate the rtc before requesting the IRQ and register it as late as possible. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index b3e33320c0bf..f77320948fc4 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -885,7 +885,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 +908,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 +935,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 */ @@ -993,6 +992,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; } -- cgit v1.2.1 From fef6853af89af94f2876f3cd765b8e49ccbbc781 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sun, 25 Feb 2018 23:15:00 +0100 Subject: rtc: m41t80: remove useless indirection m41t80_get_datetime and m41t80_set_datetime are only used after casting dev to an i2c_client. Remove that useless indirection. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m41t80.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index f77320948fc4..ad03e2f12f5d 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -198,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; @@ -232,9 +232,9 @@ static int m41t80_get_datetime(struct i2c_client *client, 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; @@ -297,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); @@ -947,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", -- cgit v1.2.1 From 7972a319d5ea5b13976051dbe5d3249ad70cbd8f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 24 Feb 2018 01:08:50 +0100 Subject: rtc: pcf85363: add .max_register in regmap_config This helps debugging as it allows reading registers from debugfs. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85363.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index 64573cccf7fe..3c5e5e1a5ead 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -157,6 +157,7 @@ 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, -- cgit v1.2.1 From fee793c46544e09e7fea41123a6903f13685eb10 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 1 Mar 2018 01:42:19 +0100 Subject: rtc: pcf85363: add alarm support Handle alarms, currently only on INTA Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85363.c | 159 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index 3c5e5e1a5ead..3fa5bda59987 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -73,6 +73,39 @@ #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 NVRAM_SIZE 0x40 static struct i2c_driver pcf85363_driver; @@ -131,11 +164,123 @@ static int pcf85363_rtc_set_time(struct device *dev, struct rtc_time *tm) buf, len); } +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 = { .read_time = pcf85363_rtc_read_time, .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) { @@ -197,6 +342,20 @@ static int pcf85363_probe(struct i2c_client *client, pcf85363->rtc->ops = &rtc_ops; + 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; -- cgit v1.2.1 From 1d30cbfc090141240681fa37775d26bb0fa12c11 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 24 Feb 2018 01:08:53 +0100 Subject: rtc: pcf85363: set time accurately As per 8.2.6 Setting and reading the time in RTC mode, first stop the clok, then reset it before setting the date and time registers. Finally, start the clock. This uses register address wrap around from 0x2f to 0x00 for efficiency. This allows to set the clock with a millisecond accuracy (drift is not corrected in this example): RTC System 1325388767 1325388767.000029180 1325388768 1325388768.000018362 1325388769 1325388769.000006544 1325388770 1325388769.999992725 1325388771 1325388770.999974544 Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85363.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/rtc/rtc-pcf85363.c b/drivers/rtc/rtc-pcf85363.c index 3fa5bda59987..c04a1edcd571 100644 --- a/drivers/rtc/rtc-pcf85363.c +++ b/drivers/rtc/rtc-pcf85363.c @@ -106,6 +106,10 @@ #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; @@ -148,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); @@ -160,8 +168,12 @@ 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) -- cgit v1.2.1 From a4ae7d3db7f12bfcac5dbace67459cd4d1741af2 Mon Sep 17 00:00:00 2001 From: Philipp Rossak Date: Mon, 26 Feb 2018 22:19:01 +0100 Subject: rtc: ac100: Fix ac100 determine rate bug This patch fixes a bug, that prevents the Allwinner A83T and the A80 from a successful boot. The bug is there since v4.16-rc1 and appeared after the clk branch was merged. You can find the shortend trace below: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = (ptrval) [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 49 Comm: kworker/0:1 Not tainted 4.15.0-10190-gb89e32ccd1be #2 Hardware name: Allwinner sun8i Family Workqueue: events deferred_probe_work_func PC is at clk_hw_get_rate+0x0/0x34 LR is at ac100_clkout_determine_rate+0x48/0x19c [ ... ] (clk_hw_get_rate) from (ac100_clkout_determine_rate+0x48/0x19c) (ac100_clkout_determine_rate) from (clk_core_set_rate_nolock+0x3c/0x1a0) (clk_core_set_rate_nolock) from (clk_set_rate+0x30/0x88) (clk_set_rate) from (of_clk_set_defaults+0x200/0x364) (of_clk_set_defaults) from (platform_drv_probe+0x18/0xb0) To fix that bug, we first check if the return of the clk_hw_get_parent_by_index is non zero. If it is zero we skip that clock parent. The BUG report could be found here: https://lkml.org/lkml/2018/2/10/198 Fixes: 04940631b8d2 ("rtc: ac100: Add clk output support") Signed-off-by: Philipp Rossak Acked-by: Maxime Ripard Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ac100.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 080e3c04be43..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); -- cgit v1.2.1 From aae82fe5537385ee494a4d8e7733ca0de260aa22 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 28 Feb 2018 22:50:53 +0100 Subject: rtc: fix rtc_time64_to_tm for 3477 The current correction for leap years will fail in 3477. 3476-12-31 being 3477-01-00 because this is 366 leap years after 1970 and 3477 isn't a leap year. Fix that by looping over until days is positive or zero. Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index ad5bb21908e5..4a3c0f3aab14 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -65,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); } -- cgit v1.2.1 From 3832123b0ac31322c1b0163f816799486278b9c2 Mon Sep 17 00:00:00 2001 From: Justin Chen Date: Mon, 26 Feb 2018 12:09:58 -0800 Subject: rtc: brcmstb-waketimer: Set wktmr prescaler The HW default is one tick per second, however instead of assuming this, lets make sure the waketimer is actually one tick per second before arming the alarm. Reviewed-by: Florian Fainelli Signed-off-by: Justin Chen Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-brcmstb-waketimer.c | 3 +++ 1 file changed, 3 insertions(+) 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); } -- cgit v1.2.1