From 38a49742de113746dfb954afe7b1b65a098a69a8 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 12 Feb 2020 09:48:36 +0100 Subject: rtc: sh: Restore devm_ioremap() alignment The alignment of the continuation of the devm_ioremap() call in sh_rtc_probe() was broken. Join the lines, as all parameters can fit on a single line. Fixes: 4bdc0d676a643140 ("remove ioremap_nocache and devm_ioremap_nocache") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20200212084836.9511-1-geert+renesas@glider.be Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sh.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index feb1f8e52c00..9167b48014a1 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -504,8 +504,7 @@ static int __init sh_rtc_probe(struct platform_device *pdev) if (unlikely(!rtc->res)) return -EBUSY; - rtc->regbase = devm_ioremap(&pdev->dev, rtc->res->start, - rtc->regsize); + rtc->regbase = devm_ioremap(&pdev->dev, rtc->res->start, rtc->regsize); if (unlikely(!rtc->regbase)) return -EINVAL; -- cgit v1.2.3 From 4594d082dbe6385c2df6b838817ccd214c16b358 Mon Sep 17 00:00:00 2001 From: Srinivas Neeli Date: Wed, 12 Feb 2020 15:54:39 +0530 Subject: rtc: zynqmp: Clear alarm interrupt status before interrupt enable Fix multiple occurring interrupts for alarm interrupt. RTC module doesn't clear the alarm interrupt status bit immediately after the interrupt is triggered.This is due to the sticky nature of the alarm interrupt status register. The alarm interrupt status register can be cleared only after the second counter outruns the set alarm value. To fix multiple spurious interrupts, disable alarm interrupt in the handler and clear the status bit before enabling the alarm interrupt. Fixes: 11143c19eb57 ("rtc: add xilinx zynqmp rtc driver") Signed-off-by: Srinivas Neeli Acked-by: Michal Simek Link: https://lore.kernel.org/r/1581503079-387-1-git-send-email-srinivas.neeli@xilinx.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-zynqmp.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 5786866c09e9..4b1077e2f826 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -38,6 +38,8 @@ #define RTC_CALIB_DEF 0x198233 #define RTC_CALIB_MASK 0x1FFFFF +#define RTC_ALRM_MASK BIT(1) +#define RTC_MSEC 1000 struct xlnx_rtc_dev { struct rtc_device *rtc; @@ -123,11 +125,28 @@ static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); + unsigned int status; + ulong timeout; + + timeout = jiffies + msecs_to_jiffies(RTC_MSEC); + + if (enabled) { + while (1) { + status = readl(xrtcdev->reg_base + RTC_INT_STS); + if (!((status & RTC_ALRM_MASK) == RTC_ALRM_MASK)) + break; + + if (time_after_eq(jiffies, timeout)) { + dev_err(dev, "Time out occur, while clearing alarm status bit\n"); + return -ETIMEDOUT; + } + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS); + } - if (enabled) writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_EN); - else + } else { writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); + } return 0; } @@ -183,8 +202,8 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id) if (!(status & (RTC_INT_SEC | RTC_INT_ALRM))) return IRQ_NONE; - /* Clear RTC_INT_ALRM interrupt only */ - writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS); + /* Disable RTC_INT_ALRM interrupt only */ + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_DIS); if (status & RTC_INT_ALRM) rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF); -- cgit v1.2.3 From a137e9b620bcf3925a8d72dd7ba723910d0bf976 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Sun, 16 Feb 2020 11:27:45 +0800 Subject: rtc: snvs: Remove unused include of of_device.h There is nothing in use from of_device.h, remove it. Signed-off-by: Anson Huang Link: https://lore.kernel.org/r/1581823666-16944-1-git-send-email-Anson.Huang@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-snvs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 757f4daa7181..7630089a113c 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 66e4f4a9cc389b277e187c115a285fad2cba5485 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 21 Feb 2020 16:47:39 +0200 Subject: rtc: cmos: Use spin_lock_irqsave() in cmos_interrupt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmos_interrupt() isn't always called from hardirq context, so we must use spin_lock_irqsave() & co. ================================ WARNING: inconsistent lock state 5.6.0-rc2-CI-CI_DRM_7981+ #1 Tainted: G U -------------------------------- inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage. rtcwake/4315 [HC0[0]:SC0[0]:HE1:SE1] takes: ffffffff82635198 (rtc_lock){?...}, at: cmos_interrupt+0x18/0x100 {IN-HARDIRQ-W} state was registered at: lock_acquire+0xa7/0x1c0 _raw_spin_lock+0x2a/0x40 cmos_interrupt+0x18/0x100 rtc_handler+0x75/0xc0 acpi_ev_fixed_event_detect+0xf9/0x132 acpi_ev_sci_xrupt_handler+0xb/0x28 acpi_irq+0x13/0x30 __handle_irq_event_percpu+0x41/0x2c0 handle_irq_event_percpu+0x2b/0x70 handle_irq_event+0x2f/0x50 handle_fasteoi_irq+0x8e/0x150 do_IRQ+0x7e/0x160 ret_from_intr+0x0/0x35 mwait_idle+0x7e/0x200 do_idle+0x1bb/0x260 cpu_startup_entry+0x14/0x20 start_secondary+0x15f/0x1b0 secondary_startup_64+0xa4/0xb0 irq event stamp: 42003 hardirqs last enabled at (42003): [] _raw_spin_unlock_irqrestore+0x47/0x60 hardirqs last disabled at (42002): [] _raw_spin_lock_irqsave+0xd/0x50 softirqs last enabled at (41848): [] __do_softirq+0x385/0x47f softirqs last disabled at (41841): [] irq_exit+0xba/0xc0 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(rtc_lock); lock(rtc_lock); *** DEADLOCK *** 6 locks held by rtcwake/4315: #0: ffff888175dc9408 (sb_writers#5){.+.+}, at: vfs_write+0x1a4/0x1d0 #1: ffff88817406ca80 (&of->mutex){+.+.}, at: kernfs_fop_write+0xdd/0x1b0 #2: ffff888179be85e0 (kn->count#236){.+.+}, at: kernfs_fop_write+0xe6/0x1b0 #3: ffffffff82641e00 (system_transition_mutex){+.+.}, at: pm_suspend+0xb3/0x3b0 #4: ffffffff826b3ee0 (acpi_scan_lock){+.+.}, at: acpi_suspend_begin+0x47/0x80 #5: ffff888178fc3960 (&dev->mutex){....}, at: device_resume+0x92/0x1c0 stack backtrace: CPU: 3 PID: 4315 Comm: rtcwake Tainted: G U 5.6.0-rc2-CI-CI_DRM_7981+ #1 Hardware name: Google Soraka/Soraka, BIOS MrChromebox-4.10 08/25/2019 Call Trace: dump_stack+0x71/0x9b mark_lock+0x49a/0x500 ? print_shortest_lock_dependencies+0x200/0x200 __lock_acquire+0x6d4/0x15d0 ? __lock_acquire+0x460/0x15d0 lock_acquire+0xa7/0x1c0 ? cmos_interrupt+0x18/0x100 _raw_spin_lock+0x2a/0x40 ? cmos_interrupt+0x18/0x100 cmos_interrupt+0x18/0x100 cmos_resume+0x1fd/0x290 ? __acpi_pm_set_device_wakeup+0x24/0x100 pnp_bus_resume+0x5e/0x90 ? pnp_bus_suspend+0x10/0x10 dpm_run_callback+0x64/0x280 device_resume+0xd4/0x1c0 ? dpm_watchdog_set+0x60/0x60 dpm_resume+0x106/0x410 ? dpm_resume_early+0x38c/0x3e0 dpm_resume_end+0x8/0x10 suspend_devices_and_enter+0x16f/0xbe0 ? rcu_read_lock_sched_held+0x4d/0x80 pm_suspend+0x344/0x3b0 state_store+0x78/0xe0 kernfs_fop_write+0x112/0x1b0 vfs_write+0xb9/0x1d0 ksys_write+0x9f/0xe0 do_syscall_64+0x4f/0x220 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7ff934307154 Code: 89 02 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 8d 05 b1 07 2e 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 41 54 55 49 89 d4 53 48 89 f5 RSP: 002b:00007ffe2647c168 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007ff934307154 RDX: 0000000000000004 RSI: 000055de3ec4e5a0 RDI: 000000000000000a RBP: 000055de3ec4e5a0 R08: 000055de3ec4c5e0 R09: 00007ff9349f3740 R10: 000055de3ec4a010 R11: 0000000000000246 R12: 000055de3ec4c500 R13: 0000000000000004 R14: 00007ff9345df2a0 R15: 00007ff9345de760 Fixes: c6d3a278cc12 ("rtc: cmos: acknowledge ACPI driven wake alarms upon resume") Fixes: 311ee9c151ad ("rtc: cmos: allow using ACPI for RTC alarm instead of HPET") Signed-off-by: Ville Syrjälä Link: https://lore.kernel.org/r/20200221144739.11746-1-ville.syrjala@linux.intel.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cmos.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index b795fe4cbd2e..fb13993fad31 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -649,10 +649,11 @@ static struct cmos_rtc cmos_rtc; static irqreturn_t cmos_interrupt(int irq, void *p) { + unsigned long flags; u8 irqstat; u8 rtc_control; - spin_lock(&rtc_lock); + spin_lock_irqsave(&rtc_lock, flags); /* When the HPET interrupt handler calls us, the interrupt * status is passed as arg1 instead of the irq number. But @@ -686,7 +687,7 @@ static irqreturn_t cmos_interrupt(int irq, void *p) hpet_mask_rtc_irq_bit(RTC_AIE); CMOS_READ(RTC_INTR_FLAGS); } - spin_unlock(&rtc_lock); + spin_unlock_irqrestore(&rtc_lock, flags); if (is_intr(irqstat)) { rtc_update_irq(p, 1, irqstat); -- cgit v1.2.3 From ae243ef0afbcbf2e68e2afd5e33753eb2e03d5d6 Mon Sep 17 00:00:00 2001 From: suguosong Date: Tue, 25 Feb 2020 10:19:23 +0800 Subject: rtc: sysfs: use kobj_to_dev use kobj_to_dev instead of open-conding it Signed-off-by: suguosong Link: https://lore.kernel.org/r/20200225021923.8570-1-guosongsu@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/sysfs.c b/drivers/rtc/sysfs.c index b7ca7d79fb28..950fac0d41ff 100644 --- a/drivers/rtc/sysfs.c +++ b/drivers/rtc/sysfs.c @@ -279,7 +279,7 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc) static umode_t rtc_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct rtc_device *rtc = to_rtc_device(dev); umode_t mode = attr->mode; -- cgit v1.2.3 From b427ca8c663ea32c67702b2ff5fb19aabd57fa7f Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 2 Mar 2020 16:13:05 +0800 Subject: rtc: snvs: Improve Kconfig dependency i.MX SNVS RTC should depend on ARCH_MXC or COMPILE_TEST. Signed-off-by: Anson Huang Link: https://lore.kernel.org/r/1583136785-4973-1-git-send-email-Anson.Huang@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 34c8b6c7e095..acaf6f98b54e 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1761,6 +1761,7 @@ config RTC_DRV_MXC_V2 config RTC_DRV_SNVS tristate "Freescale SNVS RTC support" select REGMAP_MMIO + depends on ARCH_MXC || COMPILE_TEST depends on HAS_IOMEM depends on OF help -- cgit v1.2.3 From 2911ee9e60d9013dae0abc86719e884b5dfb4fda Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 17:04:50 +0100 Subject: rtc: sirfsoc: convert to devm_rtc_allocate_device This allows further improvement of the driver. Also remove the unnecessary error string as the core will already display error messages. Link: https://lore.kernel.org/r/20200305160452.27808-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sirfsoc.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index a2c9c55667cd..b2e72597eee8 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -341,28 +341,21 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev) rtcdrv->overflow_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE); - rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &sirfsoc_rtc_ops, THIS_MODULE); - if (IS_ERR(rtcdrv->rtc)) { - err = PTR_ERR(rtcdrv->rtc); - dev_err(&pdev->dev, "can't register RTC device\n"); - return err; - } + rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtcdrv->rtc)) + return PTR_ERR(rtcdrv->rtc); + + rtcdrv->rtc->ops = &sirfsoc_rtc_ops; rtcdrv->irq = platform_get_irq(pdev, 0); - err = devm_request_irq( - &pdev->dev, - rtcdrv->irq, - sirfsoc_rtc_irq_handler, - IRQF_SHARED, - pdev->name, - rtcdrv); + err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler, + IRQF_SHARED, pdev->name, rtcdrv); if (err) { dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n"); return err; } - return 0; + return rtc_register_device(rtcdrv->rtc); } #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3 From cd65dd4180df66f5b469e2a52caae3bfe38d5526 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 17:04:51 +0100 Subject: rtc: sirfsoc: set range This RTC is a 32bit counter running at 16Hz. This overflows every eight years and a half. However, the driver uses the SW_VALUE register to store the overflow, extending the counter to 64bit as long as the update happens before the overflow. Link: https://lore.kernel.org/r/20200305160452.27808-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sirfsoc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index b2e72597eee8..8b3c88fb9793 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -346,6 +346,7 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtcdrv->rtc); rtcdrv->rtc->ops = &sirfsoc_rtc_ops; + rtcdrv->rtc->range_max = (1ULL << 60) - 1; rtcdrv->irq = platform_get_irq(pdev, 0); err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler, -- cgit v1.2.3 From 09b875a426c97bd6b2e6a56b8ca37680965524fb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 17:04:52 +0100 Subject: rtc: sirfsoc: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion to avoid the y2106 issue. Link: https://lore.kernel.org/r/20200305160452.27808-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sirfsoc.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c index 8b3c88fb9793..abf19435dbad 100644 --- a/drivers/rtc/rtc-sirfsoc.c +++ b/drivers/rtc/rtc-sirfsoc.c @@ -90,13 +90,13 @@ static int sirfsoc_rtc_read_alarm(struct device *dev, */ /* if alarm is in next overflow cycle */ if (rtc_count > rtc_alarm) - rtc_time_to_tm((rtcdrv->overflow_rtc + 1) - << (BITS_PER_LONG - RTC_SHIFT) - | rtc_alarm >> RTC_SHIFT, &(alrm->time)); + rtc_time64_to_tm((rtcdrv->overflow_rtc + 1) + << (BITS_PER_LONG - RTC_SHIFT) + | rtc_alarm >> RTC_SHIFT, &alrm->time); else - rtc_time_to_tm(rtcdrv->overflow_rtc - << (BITS_PER_LONG - RTC_SHIFT) - | rtc_alarm >> RTC_SHIFT, &(alrm->time)); + rtc_time64_to_tm(rtcdrv->overflow_rtc + << (BITS_PER_LONG - RTC_SHIFT) + | rtc_alarm >> RTC_SHIFT, &alrm->time); if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E) alrm->enabled = 1; @@ -113,7 +113,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev, rtcdrv = dev_get_drvdata(dev); if (alrm->enabled) { - rtc_tm_to_time(&(alrm->time), &rtc_alarm); + rtc_alarm = rtc_tm_to_time64(&alrm->time); spin_lock_irq(&rtcdrv->lock); @@ -181,8 +181,8 @@ static int sirfsoc_rtc_read_time(struct device *dev, cpu_relax(); } while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN)); - rtc_time_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) | - tmp_rtc >> RTC_SHIFT, tm); + rtc_time64_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT) + | tmp_rtc >> RTC_SHIFT, tm); return 0; } @@ -193,7 +193,7 @@ static int sirfsoc_rtc_set_time(struct device *dev, struct sirfsoc_rtc_drv *rtcdrv; rtcdrv = dev_get_drvdata(dev); - rtc_tm_to_time(tm, &rtc_time); + rtc_time = rtc_tm_to_time64(tm); rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT); -- cgit v1.2.3 From b1c67e0b07c5613bb7e2ad20eee9a6e5d1504fd1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 22:50:19 +0100 Subject: rtc: davinci: convert to devm_rtc_allocate_device This allows further improvement of the driver. Also remove the unnecessary error string as the core will already display error messages. Link: https://lore.kernel.org/r/20200305215022.32533-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-davinci.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 390b7351e0fe..d620d147c604 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -485,13 +485,11 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, davinci_rtc); - davinci_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &davinci_rtc_ops, THIS_MODULE); - if (IS_ERR(davinci_rtc->rtc)) { - dev_err(dev, "unable to register RTC device, err %d\n", - ret); + davinci_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(davinci_rtc->rtc)) return PTR_ERR(davinci_rtc->rtc); - } + + davinci_rtc->rtc->ops = &davinci_rtc_ops; rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); @@ -516,7 +514,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); - return 0; + return rtc_register_device(davinci_rtc->rtc); } static int __exit davinci_rtc_remove(struct platform_device *pdev) -- cgit v1.2.3 From dc924ce9a1848cf5c86c878f0df16c725788e8d3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 22:50:20 +0100 Subject: rtc: davinci: remove useless 24h alarm handling The code handling invalid alarms meaning the alarm is in the next 24 hours is not necessary since commit f8245c26886c ("rtc: remove "RTC_ALM_SET mode" bugs") which actually predates this driver. Since then, .set_alarm is never called with an invalid alarm and this handling is not necessary in the driver. Link: https://lore.kernel.org/r/20200305215022.32533-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-davinci.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index d620d147c604..3043ffea8f7c 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -413,27 +413,6 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) unsigned long flags; u16 days; - if (alm->time.tm_mday <= 0 && alm->time.tm_mon < 0 - && alm->time.tm_year < 0) { - struct rtc_time tm; - unsigned long now, then; - - davinci_rtc_read_time(dev, &tm); - rtc_tm_to_time(&tm, &now); - - alm->time.tm_mday = tm.tm_mday; - alm->time.tm_mon = tm.tm_mon; - alm->time.tm_year = tm.tm_year; - rtc_tm_to_time(&alm->time, &then); - - if (then < now) { - rtc_time_to_tm(now + 24 * 60 * 60, &tm); - alm->time.tm_mday = tm.tm_mday; - alm->time.tm_mon = tm.tm_mon; - alm->time.tm_year = tm.tm_year; - } - } - if (convert2days(&days, &alm->time) < 0) return -EINVAL; -- cgit v1.2.3 From b6d8f589204802ec531a9de69abd8563f4640d30 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 22:50:21 +0100 Subject: rtc: davinci: let the core handle rtc range Let the core handle offsetting and windowing the RTC range. This rtc has hours, minutes, seconds and 16bit days. As the driver has the RTC epoch set to year 2000, this means that the end of the range is 2^16 days minus one second later. This is Sun Jun 6 23:59:59 UTC 2179. This is better than the currently set year 2099. Link: https://lore.kernel.org/r/20200305215022.32533-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-davinci.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 3043ffea8f7c..55d826dafe1d 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -258,10 +258,6 @@ static int convert2days(u16 *days, struct rtc_time *tm) int i; *days = 0; - /* epoch == 1900 */ - if (tm->tm_year < 100 || tm->tm_year > 199) - return -EINVAL; - for (i = 2000; i < 1900 + tm->tm_year; i++) *days += rtc_year_days(1, 12, i); @@ -313,8 +309,7 @@ static int davinci_rtc_set_time(struct device *dev, struct rtc_time *tm) u8 rtc_cctrl; unsigned long flags; - if (convert2days(&days, tm) < 0) - return -EINVAL; + convert2days(&days, tm); spin_lock_irqsave(&davinci_rtc_lock, flags); @@ -413,8 +408,7 @@ static int davinci_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) unsigned long flags; u16 days; - if (convert2days(&days, &alm->time) < 0) - return -EINVAL; + convert2days(&days, &alm->time); spin_lock_irqsave(&davinci_rtc_lock, flags); @@ -469,6 +463,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) return PTR_ERR(davinci_rtc->rtc); davinci_rtc->rtc->ops = &davinci_rtc_ops; + davinci_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + davinci_rtc->rtc->range_max = RTC_TIMESTAMP_BEGIN_2000 + (1 << 16) * 86400ULL - 1; rtcif_write(davinci_rtc, PRTCIF_INTFLG_RTCSS, PRTCIF_INTFLG); rtcif_write(davinci_rtc, 0, PRTCIF_INTEN); -- cgit v1.2.3 From 6a5bbad5869132ca1d0ada05fd0c6278d7450928 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Thu, 5 Mar 2020 22:50:22 +0100 Subject: rtc: davinci: remove useless error handling convertfromdays and convert2days never return errors, stop handling non existent errors. Link: https://lore.kernel.org/r/20200305215022.32533-4-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-davinci.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 55d826dafe1d..73f87a17cdf3 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -227,7 +227,7 @@ davinci_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) return ret; } -static int convertfromdays(u16 days, struct rtc_time *tm) +static void convertfromdays(u16 days, struct rtc_time *tm) { int tmp_days, year, mon; @@ -250,10 +250,9 @@ static int convertfromdays(u16 days, struct rtc_time *tm) break; } } - return 0; } -static int convert2days(u16 *days, struct rtc_time *tm) +static void convert2days(u16 *days, struct rtc_time *tm) { int i; *days = 0; @@ -262,8 +261,6 @@ static int convert2days(u16 *days, struct rtc_time *tm) *days += rtc_year_days(1, 12, i); *days += rtc_year_days(tm->tm_mday, tm->tm_mon, 1900 + tm->tm_year); - - return 0; } static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -296,8 +293,7 @@ static int davinci_rtc_read_time(struct device *dev, struct rtc_time *tm) days <<= 8; days |= day0; - if (convertfromdays(days, tm) < 0) - return -EINVAL; + convertfromdays(days, tm); return 0; } @@ -391,8 +387,7 @@ static int davinci_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) days <<= 8; days |= day0; - if (convertfromdays(days, &alm->time) < 0) - return -EINVAL; + convertfromdays(days, &alm->time); alm->pending = !!(rtcss_read(davinci_rtc, PRTCSS_RTC_CCTRL) & -- cgit v1.2.3 From 9896169a1222a8db725fa70b3bad0d813cc3b144 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:57:28 +0100 Subject: rtc: pl030: set range This RTC is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306005730.38268-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl030.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index d4a5f8afafbc..30aa813f96c0 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -116,6 +116,7 @@ static int pl030_probe(struct amba_device *dev, const struct amba_id *id) } rtc->rtc->ops = &pl030_ops; + rtc->rtc->range_max = U32_MAX; rtc->base = ioremap(dev->res.start, resource_size(&dev->res)); if (!rtc->base) { ret = -ENOMEM; -- cgit v1.2.3 From b303b2fe5d972807407214b766c21d335414fc4b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:57:29 +0100 Subject: rtc: pl030: remove useless invalid alarm handling The core will never pass an invalid alarm to .set_alarm, it is not necessary to check for its validity. Link: https://lore.kernel.org/r/20200306005730.38268-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl030.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 30aa813f96c0..55776e8fa87c 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -46,12 +46,7 @@ static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) unsigned long time; int ret; - /* - * At the moment, we can only deal with non-wildcarded alarm times. - */ - ret = rtc_valid_tm(&alrm->time); - if (ret == 0) - ret = rtc_tm_to_time(&alrm->time, &time); + ret = rtc_tm_to_time(&alrm->time, &time); if (ret == 0) writel(time, rtc->base + RTC_MR); return ret; -- cgit v1.2.3 From c33c4713cd6bacafa27de2882e14008c4d9cc756 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:57:30 +0100 Subject: rtc: pl030: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion to avoid the y2106 issue. Link: https://lore.kernel.org/r/20200306005730.38268-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl030.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c index 55776e8fa87c..ebe03eba8f5f 100644 --- a/drivers/rtc/rtc-pl030.c +++ b/drivers/rtc/rtc-pl030.c @@ -36,27 +36,24 @@ static int pl030_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); - rtc_time_to_tm(readl(rtc->base + RTC_MR), &alrm->time); + rtc_time64_to_tm(readl(rtc->base + RTC_MR), &alrm->time); return 0; } static int pl030_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); - unsigned long time; - int ret; - ret = rtc_tm_to_time(&alrm->time, &time); - if (ret == 0) - writel(time, rtc->base + RTC_MR); - return ret; + writel(rtc_tm_to_time64(&alrm->time), rtc->base + RTC_MR); + + return 0; } static int pl030_read_time(struct device *dev, struct rtc_time *tm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); - rtc_time_to_tm(readl(rtc->base + RTC_DR), tm); + rtc_time64_to_tm(readl(rtc->base + RTC_DR), tm); return 0; } @@ -72,14 +69,10 @@ static int pl030_read_time(struct device *dev, struct rtc_time *tm) static int pl030_set_time(struct device *dev, struct rtc_time *tm) { struct pl030_rtc *rtc = dev_get_drvdata(dev); - unsigned long time; - int ret; - ret = rtc_tm_to_time(tm, &time); - if (ret == 0) - writel(time + 1, rtc->base + RTC_LR); + writel(rtc_tm_to_time64(tm) + 1, rtc->base + RTC_LR); - return ret; + return 0; } static const struct rtc_class_ops pl030_ops = { -- cgit v1.2.3 From 166b13325c5b9cfcd58954a12a0734f316d55b60 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:09 +0100 Subject: rtc: starfire: set range The starfire RTC is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306005910.38939-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-starfire.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c index a7d49329d626..f21f4f961f3a 100644 --- a/drivers/rtc/rtc-starfire.c +++ b/drivers/rtc/rtc-starfire.c @@ -39,14 +39,16 @@ static int __init starfire_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - rtc = devm_rtc_device_register(&pdev->dev, "starfire", - &starfire_rtc_ops, THIS_MODULE); + rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc)) return PTR_ERR(rtc); + rtc->ops = &starfire_rtc_ops; + rtc->range_max = U32_MAX; + platform_set_drvdata(pdev, rtc); - return 0; + return rtc_register_device(rtc); } static struct platform_driver starfire_rtc_driver = { -- cgit v1.2.3 From 326bce078a6a8b04266a816e63f6f9e74ed98457 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:10 +0100 Subject: rtc: starfire: switch to rtc_time64_to_tm Call the 64bit version of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306005910.38939-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-starfire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-starfire.c b/drivers/rtc/rtc-starfire.c index f21f4f961f3a..37a26279e107 100644 --- a/drivers/rtc/rtc-starfire.c +++ b/drivers/rtc/rtc-starfire.c @@ -27,7 +27,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); + rtc_time64_to_tm(starfire_get_time(), tm); return 0; } -- cgit v1.2.3 From 7fc9790aa38f22372c449b48ff25c71fbdd8e755 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:55 +0100 Subject: rtc: au1xxx: convert to devm_rtc_allocate_device This allows further improvement of the driver. Link: https://lore.kernel.org/r/20200306005958.39203-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-au1xxx.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index 7c5530c71285..a13ac73aa2b7 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -99,16 +99,15 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C0S) msleep(1); - rtcdev = devm_rtc_device_register(&pdev->dev, "rtc-au1xxx", - &au1xtoy_rtc_ops, THIS_MODULE); - if (IS_ERR(rtcdev)) { - ret = PTR_ERR(rtcdev); - goto out_err; - } + rtcdev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtcdev)) + return PTR_ERR(rtcdev); + + rtcdev->ops = &au1xtoy_rtc_ops; platform_set_drvdata(pdev, rtcdev); - return 0; + return rtc_register_device(rtcdev); out_err: return ret; -- cgit v1.2.3 From 9cf71edb024a919a8ed8957748885d1e1e8d231a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:56 +0100 Subject: rtc: au1xxx: remove goto label Simplify the driver by removing the goto label as it only does return ret. Link: https://lore.kernel.org/r/20200306005958.39203-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-au1xxx.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index a13ac73aa2b7..73aeb15f9491 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -65,17 +65,13 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtcdev; unsigned long t; - int ret; t = alchemy_rdsys(AU1000_SYS_CNTRCTRL); if (!(t & CNTR_OK)) { dev_err(&pdev->dev, "counters not working; aborting.\n"); - ret = -ENODEV; - goto out_err; + return -ENODEV; } - ret = -ETIMEDOUT; - /* set counter0 tickrate to 1Hz if necessary */ if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) { /* wait until hardware gives access to TRIM register */ @@ -88,7 +84,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) * counters are unusable. */ dev_err(&pdev->dev, "timeout waiting for access\n"); - goto out_err; + return -ETIMEDOUT; } /* set 1Hz TOY tick rate */ @@ -108,9 +104,6 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtcdev); return rtc_register_device(rtcdev); - -out_err: - return ret; } static struct platform_driver au1xrtc_driver = { -- cgit v1.2.3 From b1b686e4b0d165ae7c1e356ecf8da790ee8f8dcf Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:57 +0100 Subject: rtc: au1xxx: set range The Alchemy counter0 is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306005958.39203-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-au1xxx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index 73aeb15f9491..e186fb5cfffd 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -100,6 +100,7 @@ static int au1xtoy_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtcdev); rtcdev->ops = &au1xtoy_rtc_ops; + rtcdev->range_max = U32_MAX; platform_set_drvdata(pdev, rtcdev); -- cgit v1.2.3 From 0a22bd6fe46db507b4e9d3ea2db3dc8ed480b0b3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:59:58 +0100 Subject: rtc: au1xxx: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306005958.39203-4-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-au1xxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index e186fb5cfffd..791bebcb6f47 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -34,7 +34,7 @@ static int au1xtoy_rtc_read_time(struct device *dev, struct rtc_time *tm) t = alchemy_rdsys(AU1000_SYS_TOYREAD); - rtc_time_to_tm(t, tm); + rtc_time64_to_tm(t, tm); return 0; } @@ -43,7 +43,7 @@ static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned long t; - rtc_tm_to_time(tm, &t); + t = rtc_tm_to_time64(tm); alchemy_wrsys(t, AU1000_SYS_TOYWRITE); -- cgit v1.2.3 From f2997775b111c6d660c32a18d5d44d37cb7361b1 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:01:44 +0100 Subject: rtc: sa1100: fix possible race condition Both RTC IRQs are requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in the IRQ handler. To fix this issue, allocating the rtc_device struct before requesting the IRQs using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device. Link: https://lore.kernel.org/r/20200306010146.39762-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sa1100.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index d37893f6eaee..97c352594033 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -182,7 +182,6 @@ static const struct rtc_class_ops sa1100_rtc_ops = { int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) { - struct rtc_device *rtc; int ret; spin_lock_init(&info->lock); @@ -211,15 +210,14 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) writel_relaxed(0, info->rcnr); } - rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &sa1100_rtc_ops, - THIS_MODULE); - if (IS_ERR(rtc)) { + info->rtc->ops = &sa1100_rtc_ops; + info->rtc->max_user_freq = RTC_FREQ; + + ret = rtc_register_device(info->rtc); + if (ret) { clk_disable_unprepare(info->clk); - return PTR_ERR(rtc); + return ret; } - info->rtc = rtc; - - rtc->max_user_freq = RTC_FREQ; /* Fix for a nasty initialization problem the in SA11xx RTSR register. * See also the comments in sa1100_rtc_interrupt(). @@ -267,6 +265,10 @@ static int sa1100_rtc_probe(struct platform_device *pdev) info->irq_1hz = irq_1hz; info->irq_alarm = irq_alarm; + info->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc)) + return PTR_ERR(info->rtc); + ret = devm_request_irq(&pdev->dev, irq_1hz, sa1100_rtc_interrupt, 0, "rtc 1Hz", &pdev->dev); if (ret) { -- cgit v1.2.3 From e877ab73028f783f5b0ce09b9bbcaaa30e1bebbe Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:01:45 +0100 Subject: rtc: sa1100: set range The SA1100 RTC is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306010146.39762-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sa1100.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 97c352594033..82a9d4ab368f 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -212,6 +212,7 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) info->rtc->ops = &sa1100_rtc_ops; info->rtc->max_user_freq = RTC_FREQ; + info->rtc->range_max = U32_MAX; ret = rtc_register_device(info->rtc); if (ret) { -- cgit v1.2.3 From eb8d94203292c9d7be2dacd97e80b4d128e9f6a2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:01:46 +0100 Subject: rtc: sa1100: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306010146.39762-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sa1100.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 82a9d4ab368f..9ccc97cf5e09 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c @@ -111,20 +111,17 @@ static int sa1100_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct sa1100_rtc *info = dev_get_drvdata(dev); - rtc_time_to_tm(readl_relaxed(info->rcnr), tm); + rtc_time64_to_tm(readl_relaxed(info->rcnr), tm); return 0; } static int sa1100_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct sa1100_rtc *info = dev_get_drvdata(dev); - unsigned long time; - int ret; - ret = rtc_tm_to_time(tm, &time); - if (ret == 0) - writel_relaxed(time, info->rcnr); - return ret; + writel_relaxed(rtc_tm_to_time64(tm), info->rcnr); + + return 0; } static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) @@ -141,24 +138,18 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct sa1100_rtc *info = dev_get_drvdata(dev); - unsigned long time; - int ret; spin_lock_irq(&info->lock); - ret = rtc_tm_to_time(&alrm->time, &time); - if (ret != 0) - goto out; writel_relaxed(readl_relaxed(info->rtsr) & (RTSR_HZE | RTSR_ALE | RTSR_AL), info->rtsr); - writel_relaxed(time, info->rtar); + writel_relaxed(rtc_tm_to_time64(&alrm->time), info->rtar); if (alrm->enabled) writel_relaxed(readl_relaxed(info->rtsr) | RTSR_ALE, info->rtsr); else writel_relaxed(readl_relaxed(info->rtsr) & ~RTSR_ALE, info->rtsr); -out: spin_unlock_irq(&info->lock); - return ret; + return 0; } static int sa1100_rtc_proc(struct device *dev, struct seq_file *seq) -- cgit v1.2.3 From 05b38d182c5deeadb1b7eeb3e35c35b7652dc0e8 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:57:01 +0100 Subject: rtc: cpcap: convert to devm_rtc_allocate_device This allows further improvement of the driver. Link: https://lore.kernel.org/r/20200306015703.42101-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cpcap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index 6a3b70fd7e1f..35f0717661b3 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -256,12 +256,12 @@ static int cpcap_rtc_probe(struct platform_device *pdev) return -ENODEV; platform_set_drvdata(pdev, rtc); - rtc->rtc_dev = devm_rtc_device_register(dev, "cpcap_rtc", - &cpcap_rtc_ops, THIS_MODULE); - + rtc->rtc_dev = devm_rtc_allocate_device(dev); if (IS_ERR(rtc->rtc_dev)) return PTR_ERR(rtc->rtc_dev); + rtc->rtc_dev->ops = &cpcap_rtc_ops; + err = cpcap_get_vendor(dev, rtc->regmap, &rtc->vendor); if (err) return err; @@ -298,7 +298,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev) /* ignore error and continue without wakeup support */ } - return 0; + return rtc_register_device(rtc->rtc_dev); } static const struct of_device_id cpcap_rtc_of_match[] = { -- cgit v1.2.3 From d2377f8cc5a7add7ba78db8122cf33e83c47d525 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:57:02 +0100 Subject: rtc: cpcap: set range The CPCAP rtc is a 14bit day counter plus a 17bit seconds counter. Note that this failed on Nov 10 2014 so it is very likely this driver as never been used since. Link: https://lore.kernel.org/r/20200306015703.42101-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cpcap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index 35f0717661b3..38f949730b1b 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -261,6 +261,7 @@ static int cpcap_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->rtc_dev); rtc->rtc_dev->ops = &cpcap_rtc_ops; + rtc->rtc_dev->range_max = (1 << 14) * SECS_PER_DAY - 1; err = cpcap_get_vendor(dev, rtc->regmap, &rtc->vendor); if (err) -- cgit v1.2.3 From d238df15e5cdfae54688ed9c1b33e19ed747dcda Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:57:03 +0100 Subject: rtc: cpcap: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306015703.42101-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-cpcap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cpcap.c b/drivers/rtc/rtc-cpcap.c index 38f949730b1b..a603f1f21125 100644 --- a/drivers/rtc/rtc-cpcap.c +++ b/drivers/rtc/rtc-cpcap.c @@ -56,14 +56,14 @@ static void cpcap2rtc_time(struct rtc_time *rtc, struct cpcap_time *cpcap) tod = (cpcap->tod1 & TOD1_MASK) | ((cpcap->tod2 & TOD2_MASK) << 8); time = tod + ((cpcap->day & DAY_MASK) * SECS_PER_DAY); - rtc_time_to_tm(time, rtc); + rtc_time64_to_tm(time, rtc); } static void rtc2cpcap_time(struct cpcap_time *cpcap, struct rtc_time *rtc) { unsigned long time; - rtc_tm_to_time(rtc, &time); + time = rtc_tm_to_time64(rtc); cpcap->day = time / SECS_PER_DAY; time %= SECS_PER_DAY; -- cgit v1.2.3 From c11af8131a4e7ba1960faed731ee7e84c2c13c94 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:34:01 +0100 Subject: rtc: ds1374: fix possible race condition The RTC IRQ is requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in the IRQ handler. To fix this issue, allocating the rtc_device struct before requesting the RTC IRQ using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device. Link: https://lore.kernel.org/r/20200306073404.56921-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1374.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 6e9ddcd03992..cb18a11a3c76 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -620,6 +620,10 @@ static int ds1374_probe(struct i2c_client *client, if (!ds1374) return -ENOMEM; + ds1374->rtc = devm_rtc_allocate_device(&client->dev); + if (IS_ERR(ds1374->rtc)) + return PTR_ERR(ds1374->rtc); + ds1374->client = client; i2c_set_clientdata(client, ds1374); @@ -641,12 +645,11 @@ static int ds1374_probe(struct i2c_client *client, device_set_wakeup_capable(&client->dev, 1); } - ds1374->rtc = devm_rtc_device_register(&client->dev, client->name, - &ds1374_rtc_ops, THIS_MODULE); - if (IS_ERR(ds1374->rtc)) { - dev_err(&client->dev, "unable to register the class device\n"); - return PTR_ERR(ds1374->rtc); - } + ds1374->rtc->ops = &ds1374_rtc_ops; + + ret = rtc_register_device(ds1374->rtc); + if (ret) + return ret; #ifdef CONFIG_RTC_DRV_DS1374_WDT save_client = client; -- cgit v1.2.3 From 4136ff3a515752327baad3b78e3452af13bfdd05 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:34:02 +0100 Subject: rtc: ds1374: set range The ds1374 is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306073404.56921-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1374.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index cb18a11a3c76..843fcbf5e940 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -646,6 +646,7 @@ static int ds1374_probe(struct i2c_client *client, } ds1374->rtc->ops = &ds1374_rtc_ops; + ds1374->rtc->range_max = U32_MAX; ret = rtc_register_device(ds1374->rtc); if (ret) -- cgit v1.2.3 From ca824be9b394a7bab7e01269bde7e7986ca81ccc Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:34:03 +0100 Subject: rtc: ds1374: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306073404.56921-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1374.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c index 843fcbf5e940..9c51a12cf70f 100644 --- a/drivers/rtc/rtc-ds1374.c +++ b/drivers/rtc/rtc-ds1374.c @@ -164,7 +164,7 @@ static int ds1374_read_time(struct device *dev, struct rtc_time *time) ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4); if (!ret) - rtc_time_to_tm(itime, time); + rtc_time64_to_tm(itime, time); return ret; } @@ -172,9 +172,8 @@ static int ds1374_read_time(struct device *dev, struct rtc_time *time) static int ds1374_set_time(struct device *dev, struct rtc_time *time) { struct i2c_client *client = to_i2c_client(dev); - unsigned long itime; + unsigned long itime = rtc_tm_to_time64(time); - rtc_tm_to_time(time, &itime); return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4); } @@ -212,7 +211,7 @@ static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (ret) goto out; - rtc_time_to_tm(now + cur_alarm, &alarm->time); + rtc_time64_to_tm(now + cur_alarm, &alarm->time); alarm->enabled = !!(cr & DS1374_REG_CR_WACE); alarm->pending = !!(sr & DS1374_REG_SR_AF); @@ -237,8 +236,8 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) if (ret < 0) return ret; - rtc_tm_to_time(&alarm->time, &new_alarm); - rtc_tm_to_time(&now, &itime); + new_alarm = rtc_tm_to_time64(&alarm->time); + itime = rtc_tm_to_time64(&now); /* This can happen due to races, in addition to dates that are * truly in the past. To avoid requiring the caller to check for -- cgit v1.2.3 From 9869a93c823bc7fe2fba7407ea25f400c8f98e61 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:34:58 +0100 Subject: rtc: ds1305: set range The ds1305 is a BCD rtc valid from 2000 to 2099. Link: https://lore.kernel.org/r/20200306073459.57197-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1305.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index 4420fbf2f8fe..ca55ebab24fb 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -694,6 +694,8 @@ static int ds1305_probe(struct spi_device *spi) return PTR_ERR(ds1305->rtc); ds1305->rtc->ops = &ds1305_ops; + ds1305->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + ds1305->rtc->range_max = RTC_TIMESTAMP_END_2099; ds1305_nvmem_cfg.priv = ds1305; ds1305->rtc->nvram_old_abi = true; -- cgit v1.2.3 From f2adcb9c3abde5470c0cfbd74e40dec820a40153 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:34:59 +0100 Subject: rtc: ds1305: switch to rtc_tm_to_time64 Call the 64bit version of rtc_tm to time conversion. Link: https://lore.kernel.org/r/20200306073459.57197-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1305.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c index ca55ebab24fb..a3d790889eea 100644 --- a/drivers/rtc/rtc-ds1305.c +++ b/drivers/rtc/rtc-ds1305.c @@ -325,17 +325,13 @@ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm) u8 buf[1 + DS1305_ALM_LEN]; /* convert desired alarm to time_t */ - status = rtc_tm_to_time(&alm->time, &later); - if (status < 0) - return status; + later = rtc_tm_to_time64(&alm->time); /* Read current time as time_t */ status = ds1305_get_time(dev, &tm); if (status < 0) return status; - status = rtc_tm_to_time(&tm, &now); - if (status < 0) - return status; + now = rtc_tm_to_time64(&tm); /* make sure alarm fires within the next 24 hours */ if (later <= now) -- cgit v1.2.3 From d5d55b70984086bffe7a6321c0d28d3c7f41b9fa Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:37:55 +0100 Subject: rtc: pm8xxx: convert to devm_rtc_allocate_device This allows further improvement of the driver. Also remove the unnecessary error string as the core will already display error messages. Link: https://lore.kernel.org/r/20200306073758.58050-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 07ea1be3abb9..b97333c95e53 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -486,13 +486,11 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); /* Register the RTC device */ - rtc_dd->rtc = devm_rtc_device_register(&pdev->dev, "pm8xxx_rtc", - &pm8xxx_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc_dd->rtc)) { - dev_err(&pdev->dev, "%s: RTC registration failed (%ld)\n", - __func__, PTR_ERR(rtc_dd->rtc)); + rtc_dd->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(rtc_dd->rtc)) return PTR_ERR(rtc_dd->rtc); - } + + rtc_dd->rtc->ops = &pm8xxx_rtc_ops; /* Request the alarm IRQ */ rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->rtc_alarm_irq, @@ -504,9 +502,7 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) return rc; } - dev_dbg(&pdev->dev, "Probe success !!\n"); - - return 0; + return rtc_register_device(rtc_dd->rtc); } #ifdef CONFIG_PM_SLEEP -- cgit v1.2.3 From 3cfe52607779a5c3752a73033a86385789ceb742 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:37:56 +0100 Subject: rtc: pm8xxx: set range The pm8xxx are 32bit seconds counter. Link: https://lore.kernel.org/r/20200306073758.58050-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index b97333c95e53..71bd56d32c90 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -491,6 +491,7 @@ static int pm8xxx_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc_dd->rtc); rtc_dd->rtc->ops = &pm8xxx_rtc_ops; + rtc_dd->rtc->range_max = U32_MAX; /* Request the alarm IRQ */ rc = devm_request_any_context_irq(&pdev->dev, rtc_dd->rtc_alarm_irq, -- cgit v1.2.3 From 4c470b2f121365800972b71e787aae359ff186a7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:37:57 +0100 Subject: rtc: pm8xxx: : switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306073758.58050-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 71bd56d32c90..2da0d80224c3 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -84,7 +84,7 @@ static int pm8xxx_rtc_set_time(struct device *dev, struct rtc_time *tm) if (!rtc_dd->allow_set_time) return -EACCES; - rtc_tm_to_time(tm, &secs); + secs = rtc_tm_to_time64(tm); dev_dbg(dev, "Seconds value to be written to RTC = %lu\n", secs); @@ -208,7 +208,7 @@ static int pm8xxx_rtc_read_time(struct device *dev, struct rtc_time *tm) secs = value[0] | (value[1] << 8) | (value[2] << 16) | ((unsigned long)value[3] << 24); - rtc_time_to_tm(secs, tm); + rtc_time64_to_tm(secs, tm); dev_dbg(dev, "secs = %lu, h:m:s == %ptRt, y-m-d = %ptRdr\n", secs, tm, tm); @@ -224,7 +224,7 @@ static int pm8xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; - rtc_tm_to_time(&alarm->time, &secs); + secs = rtc_tm_to_time64(&alarm->time); for (i = 0; i < NUM_8_BIT_RTC_REGS; i++) { value[i] = secs & 0xFF; @@ -280,7 +280,7 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) secs = value[0] | (value[1] << 8) | (value[2] << 16) | ((unsigned long)value[3] << 24); - rtc_time_to_tm(secs, &alarm->time); + rtc_time64_to_tm(secs, &alarm->time); rc = rtc_valid_tm(&alarm->time); if (rc < 0) { -- cgit v1.2.3 From c47cf9d6bb7bc0c2ca917602c60bd79bcb0d35df Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:37:58 +0100 Subject: rtc: pm8xxx: stop validating valid alarm time rtc_time64_to_tm never generates an invalid rtc_tm, stop validating it. Link: https://lore.kernel.org/r/20200306073758.58050-4-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index 2da0d80224c3..e3d9abb2134e 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -282,12 +282,6 @@ static int pm8xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) rtc_time64_to_tm(secs, &alarm->time); - rc = rtc_valid_tm(&alarm->time); - if (rc < 0) { - dev_err(dev, "Invalid alarm time read from RTC\n"); - return rc; - } - dev_dbg(dev, "Alarm set for - h:m:s=%ptRt, y-m-d=%ptRdr\n", &alarm->time, &alarm->time); -- cgit v1.2.3 From d53d4ae981d065a63423b0fe64d18827ed540349 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:44:00 +0100 Subject: rtc: mpc5121: simplify probe Use devm managed function to simplify probe and remove. Link: https://lore.kernel.org/r/20200306074404.58909-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mpc5121.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 15a9d0278778..9e4454d35352 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -315,8 +315,8 @@ static int mpc5121_rtc_probe(struct platform_device *op) if (!rtc) return -ENOMEM; - rtc->regs = of_iomap(op->dev.of_node, 0); - if (!rtc->regs) { + rtc->regs = devm_platform_ioremap_resource(op, 0); + if (IS_ERR(rtc->regs)) { dev_err(&op->dev, "%s: couldn't map io space\n", __func__); return -ENOSYS; } @@ -326,8 +326,8 @@ static int mpc5121_rtc_probe(struct platform_device *op) platform_set_drvdata(op, rtc); rtc->irq = irq_of_parse_and_map(op->dev.of_node, 1); - err = request_irq(rtc->irq, mpc5121_rtc_handler, 0, - "mpc5121-rtc", &op->dev); + err = devm_request_irq(&op->dev, rtc->irq, mpc5121_rtc_handler, 0, + "mpc5121-rtc", &op->dev); if (err) { dev_err(&op->dev, "%s: could not request irq: %i\n", __func__, rtc->irq); @@ -335,8 +335,9 @@ static int mpc5121_rtc_probe(struct platform_device *op) } rtc->irq_periodic = irq_of_parse_and_map(op->dev.of_node, 0); - err = request_irq(rtc->irq_periodic, mpc5121_rtc_handler_upd, - 0, "mpc5121-rtc_upd", &op->dev); + err = devm_request_irq(&op->dev, rtc->irq_periodic, + mpc5121_rtc_handler_upd, 0, "mpc5121-rtc_upd", + &op->dev); if (err) { dev_err(&op->dev, "%s: could not request irq: %i\n", __func__, rtc->irq_periodic); @@ -361,20 +362,16 @@ static int mpc5121_rtc_probe(struct platform_device *op) if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); - goto out_free_irq; + goto out_dispose2; } rtc->rtc->uie_unsupported = 1; return 0; -out_free_irq: - free_irq(rtc->irq_periodic, &op->dev); out_dispose2: irq_dispose_mapping(rtc->irq_periodic); - free_irq(rtc->irq, &op->dev); out_dispose: irq_dispose_mapping(rtc->irq); - iounmap(rtc->regs); return err; } @@ -388,9 +385,6 @@ static int mpc5121_rtc_remove(struct platform_device *op) out_8(®s->alm_enable, 0); out_8(®s->int_enable, in_8(®s->int_enable) & ~0x1); - iounmap(rtc->regs); - free_irq(rtc->irq, &op->dev); - free_irq(rtc->irq_periodic, &op->dev); irq_dispose_mapping(rtc->irq); irq_dispose_mapping(rtc->irq_periodic); -- cgit v1.2.3 From fffbe10e2fd3a92a401cbcbb77da7f67fe900eeb Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:44:01 +0100 Subject: rtc: mpc5121: convert to devm_rtc_allocate_device This simplifies the path for the rtc_ops selection. Link: https://lore.kernel.org/r/20200306074404.58909-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mpc5121.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 9e4454d35352..845212fd1e33 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -344,6 +344,15 @@ static int mpc5121_rtc_probe(struct platform_device *op) goto out_dispose2; } + rtc->rtc = devm_rtc_allocate_device(&op->dev); + if (IS_ERR(rtc->rtc)) { + err = PTR_ERR(rtc->rtc); + goto out_dispose2; + } + + rtc->rtc->ops = &mpc5200_rtc_ops; + rtc->rtc->uie_unsupported = 1; + if (of_device_is_compatible(op->dev.of_node, "fsl,mpc5121-rtc")) { u32 ka; ka = in_be32(&rtc->regs->keep_alive); @@ -352,19 +361,12 @@ static int mpc5121_rtc_probe(struct platform_device *op) "mpc5121-rtc: Battery or oscillator failure!\n"); out_be32(&rtc->regs->keep_alive, ka); } - - rtc->rtc = devm_rtc_device_register(&op->dev, "mpc5121-rtc", - &mpc5121_rtc_ops, THIS_MODULE); - } else { - rtc->rtc = devm_rtc_device_register(&op->dev, "mpc5200-rtc", - &mpc5200_rtc_ops, THIS_MODULE); + rtc->rtc->ops = &mpc5121_rtc_ops; } - if (IS_ERR(rtc->rtc)) { - err = PTR_ERR(rtc->rtc); + err = rtc_register_device(rtc->rtc); + if (err) goto out_dispose2; - } - rtc->rtc->uie_unsupported = 1; return 0; -- cgit v1.2.3 From 3905d1c02dc9dd0b498567f52380bcd9ce6420af Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:44:02 +0100 Subject: rtc: mpc5121: set range The datasheet states that 4052 is the maximum value for year. However, the mpc5121 read_time and set_time function abuse the target time register instead of using the broken down time so it is limited to 2106. Link: https://lore.kernel.org/r/20200306074404.58909-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mpc5121.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 845212fd1e33..5507f1847f7c 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -352,6 +352,8 @@ static int mpc5121_rtc_probe(struct platform_device *op) rtc->rtc->ops = &mpc5200_rtc_ops; rtc->rtc->uie_unsupported = 1; + rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; + rtc->rtc->range_max = 65733206399ULL; /* 4052-12-31 23:59:59 */ if (of_device_is_compatible(op->dev.of_node, "fsl,mpc5121-rtc")) { u32 ka; @@ -362,6 +364,13 @@ static int mpc5121_rtc_probe(struct platform_device *op) out_be32(&rtc->regs->keep_alive, ka); } rtc->rtc->ops = &mpc5121_rtc_ops; + /* + * This is a limitation of the driver that abuses the target + * time register, the actual maximum year for the mpc5121 is + * also 4052. + */ + rtc->rtc->range_min = 0; + rtc->rtc->range_max = U32_MAX; } err = rtc_register_device(rtc->rtc); -- cgit v1.2.3 From 3d5a49545ac549c122b24c2af730ad00093e5d1f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:44:03 +0100 Subject: rtc: mpc5121: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306074404.58909-4-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mpc5121.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mpc5121.c b/drivers/rtc/rtc-mpc5121.c index 5507f1847f7c..3040844129ce 100644 --- a/drivers/rtc/rtc-mpc5121.c +++ b/drivers/rtc/rtc-mpc5121.c @@ -111,7 +111,7 @@ static int mpc5121_rtc_read_time(struct device *dev, struct rtc_time *tm) */ now = in_be32(®s->actual_time) + in_be32(®s->target_time); - rtc_time_to_tm(now, tm); + rtc_time64_to_tm(now, tm); /* * update second minute hour registers @@ -126,16 +126,14 @@ static int mpc5121_rtc_set_time(struct device *dev, struct rtc_time *tm) { struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); struct mpc5121_rtc_regs __iomem *regs = rtc->regs; - int ret; unsigned long now; /* * The actual_time register is read only so we write the offset * between it and linux time to the target_time register. */ - ret = rtc_tm_to_time(tm, &now); - if (ret == 0) - out_be32(®s->target_time, now - in_be32(®s->actual_time)); + now = rtc_tm_to_time64(tm); + out_be32(®s->target_time, now - in_be32(®s->actual_time)); /* * update second minute hour registers -- cgit v1.2.3 From 7098f5368268800a65cc45d91b42281dd0572514 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 14:16:28 +0100 Subject: rtc: fsl-ftm-alarm: allow COMPILE_TEST Allow building building the driver with COMPILE_TEST. Link: https://lore.kernel.org/r/20200306131629.18837-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index acaf6f98b54e..777047620ec7 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1334,7 +1334,7 @@ config RTC_DRV_IMXDI config RTC_DRV_FSL_FTM_ALARM tristate "Freescale FlexTimer alarm timer" - depends on ARCH_LAYERSCAPE || SOC_LS1021A + depends on ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST help For the FlexTimer in LS1012A, LS1021A, LS1028A, LS1043A, LS1046A, LS1088A, LS208xA, we can use FTM as the wakeup source. -- cgit v1.2.3 From 61c9fbff9d62e1de214f15c0f9c692a81430f4ff Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:58:07 +0100 Subject: rtc: pl031: remove useless invalid alarm handling The core will never pass an invalid alarm to .set_alarm, it is not necessary to check for its validity. Acked-by: Linus Walleij Link: https://lore.kernel.org/r/20200306005809.38530-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl031.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 180caebbd355..2e8e019a6e4c 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -210,17 +210,13 @@ static int pl031_stv2_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) unsigned long bcd_year; int ret; - /* At the moment, we can only deal with non-wildcarded alarm times. */ - ret = rtc_valid_tm(&alarm->time); + ret = pl031_stv2_tm_to_time(dev, &alarm->time, + &time, &bcd_year); if (ret == 0) { - ret = pl031_stv2_tm_to_time(dev, &alarm->time, - &time, &bcd_year); - if (ret == 0) { - writel(bcd_year, ldata->base + RTC_YMR); - writel(time, ldata->base + RTC_MR); + writel(bcd_year, ldata->base + RTC_YMR); + writel(time, ldata->base + RTC_MR); - pl031_alarm_irq_enable(dev, alarm->enabled); - } + pl031_alarm_irq_enable(dev, alarm->enabled); } return ret; @@ -285,14 +281,10 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) unsigned long time; int ret; - /* At the moment, we can only deal with non-wildcarded alarm times. */ - ret = rtc_valid_tm(&alarm->time); + ret = rtc_tm_to_time(&alarm->time, &time); if (ret == 0) { - ret = rtc_tm_to_time(&alarm->time, &time); - if (ret == 0) { - writel(time, ldata->base + RTC_MR); - pl031_alarm_irq_enable(dev, alarm->enabled); - } + writel(time, ldata->base + RTC_MR); + pl031_alarm_irq_enable(dev, alarm->enabled); } return ret; -- cgit v1.2.3 From 03f2a0e45f395bc34b0a44105bc7e935bfd40c27 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:58:08 +0100 Subject: rtc: pl031: set range The PL031 and ST v1 RTC are 32bit seconds counters. STv2 is a BCD RTC apparently going from 0000 to 9999, hopefully handling the leap days properly until then. Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20200306005809.38530-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl031.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 2e8e019a6e4c..07dc0f264100 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -80,6 +80,8 @@ struct pl031_vendor_data { bool clockwatch; bool st_weekday; unsigned long irqflags; + time64_t range_min; + timeu64_t range_max; }; struct pl031_local { @@ -375,6 +377,8 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) return PTR_ERR(ldata->rtc); ldata->rtc->ops = ops; + ldata->rtc->range_min = vendor->range_min; + ldata->rtc->range_max = vendor->range_max; ret = rtc_register_device(ldata->rtc); if (ret) @@ -405,6 +409,7 @@ static struct pl031_vendor_data arm_pl031 = { .set_alarm = pl031_set_alarm, .alarm_irq_enable = pl031_alarm_irq_enable, }, + .range_max = U32_MAX, }; /* The First ST derivative */ @@ -418,6 +423,7 @@ static struct pl031_vendor_data stv1_pl031 = { }, .clockwatch = true, .st_weekday = true, + .range_max = U32_MAX, }; /* And the second ST derivative */ @@ -438,6 +444,8 @@ static struct pl031_vendor_data stv2_pl031 = { * remove IRQF_COND_SUSPEND */ .irqflags = IRQF_SHARED | IRQF_COND_SUSPEND, + .range_min = RTC_TIMESTAMP_BEGIN_0000, + .range_max = RTC_TIMESTAMP_END_9999, }; static const struct amba_id pl031_ids[] = { -- cgit v1.2.3 From c8ff5841a90bdd99f28f7062c99b3058005c1c32 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 01:58:09 +0100 Subject: rtc: pl031: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion to allow extending support after 2106 and properly supporting the STv2 range. Acked-by: Linus Walleij Link: https://lore.kernel.org/r/20200306005809.38530-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pl031.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c index 07dc0f264100..40d7450a1ce4 100644 --- a/drivers/rtc/rtc-pl031.c +++ b/drivers/rtc/rtc-pl031.c @@ -125,11 +125,9 @@ static int pl031_stv2_tm_to_time(struct device *dev, return -EINVAL; } else if (wday == -1) { /* wday is not provided, calculate it here */ - unsigned long time; struct rtc_time calc_tm; - rtc_tm_to_time(tm, &time); - rtc_time_to_tm(time, &calc_tm); + rtc_time64_to_tm(rtc_tm_to_time64(tm), &calc_tm); wday = calc_tm.tm_wday; } @@ -246,30 +244,25 @@ static int pl031_read_time(struct device *dev, struct rtc_time *tm) { struct pl031_local *ldata = dev_get_drvdata(dev); - rtc_time_to_tm(readl(ldata->base + RTC_DR), tm); + rtc_time64_to_tm(readl(ldata->base + RTC_DR), tm); return 0; } static int pl031_set_time(struct device *dev, struct rtc_time *tm) { - unsigned long time; struct pl031_local *ldata = dev_get_drvdata(dev); - int ret; - ret = rtc_tm_to_time(tm, &time); - - if (ret == 0) - writel(time, ldata->base + RTC_LR); + writel(rtc_tm_to_time64(tm), ldata->base + RTC_LR); - return ret; + return 0; } static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct pl031_local *ldata = dev_get_drvdata(dev); - rtc_time_to_tm(readl(ldata->base + RTC_MR), &alarm->time); + rtc_time64_to_tm(readl(ldata->base + RTC_MR), &alarm->time); alarm->pending = readl(ldata->base + RTC_RIS) & RTC_BIT_AI; alarm->enabled = readl(ldata->base + RTC_IMSC) & RTC_BIT_AI; @@ -280,16 +273,10 @@ static int pl031_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) { struct pl031_local *ldata = dev_get_drvdata(dev); - unsigned long time; - int ret; - ret = rtc_tm_to_time(&alarm->time, &time); - if (ret == 0) { - writel(time, ldata->base + RTC_MR); - pl031_alarm_irq_enable(dev, alarm->enabled); - } + writel(rtc_tm_to_time64(&alarm->time), ldata->base + RTC_MR); - return ret; + return 0; } static int pl031_remove(struct amba_device *adev) -- cgit v1.2.3 From a5965a31012f3e80105eb759fa69eded6a813a4b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:01:01 +0100 Subject: rtc: ab8500: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Acked-by: Linus Walleij Link: https://lore.kernel.org/r/20200306010101.39517-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ab8500.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 8492ffed4ca6..3d60f3283f11 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -100,7 +100,7 @@ static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) secs = secs / COUNTS_PER_SEC; secs = secs + (mins * 60); - rtc_time_to_tm(secs, tm); + rtc_time64_to_tm(secs, tm); return 0; } @@ -110,7 +110,7 @@ static int ab8500_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; unsigned long no_secs, no_mins, secs = 0; - rtc_tm_to_time(tm, &secs); + secs = rtc_tm_to_time64(tm); no_mins = secs / 60; @@ -168,7 +168,7 @@ static int ab8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); secs = mins * 60; - rtc_time_to_tm(secs, &alarm->time); + rtc_time64_to_tm(secs, &alarm->time); return 0; } @@ -188,7 +188,7 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) struct rtc_time curtm; /* Get the number of seconds since 1970 */ - rtc_tm_to_time(&alarm->time, &secs); + secs = rtc_tm_to_time64(&alarm->time); /* * Check whether alarm is set less than 1min. @@ -196,7 +196,7 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON */ ab8500_rtc_read_time(dev, &curtm); /* Read current time */ - rtc_tm_to_time(&curtm, &cursec); + cursec = rtc_tm_to_time64(&curtm); if ((secs - cursec) < 59) { dev_dbg(dev, "Alarm less than 1 minute not supported\r\n"); return -EINVAL; -- cgit v1.2.3 From a04b3b965f3d5a1b0b00c2b546b30ee09ce112db Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:02:38 +0100 Subject: rtc: puv3: set range This RTC is a 32bit seconds counter. Link: https://lore.kernel.org/r/20200306010240.40056-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-puv3.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index 89ff713163dd..3029a52a501e 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -234,6 +234,7 @@ static int puv3_rtc_probe(struct platform_device *pdev) /* register RTC and exit */ rtc->ops = &puv3_rtcops; + rtc->range_max = U32_MAX; ret = rtc_register_device(rtc); if (ret) goto err_nortc; -- cgit v1.2.3 From 0155b547746fefbe2e0e7938785309d63725e1ba Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 02:02:39 +0100 Subject: rtc: puv3: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200306010240.40056-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-puv3.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-puv3.c b/drivers/rtc/rtc-puv3.c index 3029a52a501e..954b88d2485f 100644 --- a/drivers/rtc/rtc-puv3.c +++ b/drivers/rtc/rtc-puv3.c @@ -85,7 +85,7 @@ static int puv3_rtc_setpie(struct device *dev, int enabled) /* Time read/write */ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) { - rtc_time_to_tm(readl(RTC_RCNR), rtc_tm); + rtc_time64_to_tm(readl(RTC_RCNR), rtc_tm); dev_dbg(dev, "read time %ptRr\n", rtc_tm); @@ -94,12 +94,9 @@ static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm) { - unsigned long rtc_count = 0; - dev_dbg(dev, "set time %ptRr\n", tm); - rtc_tm_to_time(tm, &rtc_count); - writel(rtc_count, RTC_RCNR); + writel(rtc_tm_to_time64(tm), RTC_RCNR); return 0; } @@ -108,7 +105,7 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time *alm_tm = &alrm->time; - rtc_time_to_tm(readl(RTC_RTAR), alm_tm); + rtc_time64_to_tm(readl(RTC_RTAR), alm_tm); alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE; @@ -120,12 +117,10 @@ static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time *tm = &alrm->time; - unsigned long rtcalarm_count = 0; dev_dbg(dev, "set alarm: %d, %ptRr\n", alrm->enabled, tm); - rtc_tm_to_time(tm, &rtcalarm_count); - writel(rtcalarm_count, RTC_RTAR); + writel(rtc_tm_to_time64(tm), RTC_RTAR); puv3_rtc_setaie(dev, alrm->enabled); -- cgit v1.2.3 From ec98a87509f40324807dc179a7e3163d40709eba Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 8 Mar 2020 14:58:48 +0100 Subject: rtc: sun6i: Make external 32k oscillator optional Some boards, like OrangePi PC2 (H5), OrangePi Plus 2E (H3) and Tanix TX6 (H6) don't have external 32kHz oscillator. Till H6, it didn't really matter if external oscillator was enabled because HW detected error and fall back to internal one. H6 has same functionality but it's the first SoC which have "auto switch bypass" bit documented and always enabled in driver. This prevents RTC to work correctly if external crystal is not present on board. There are other side effects - all peripherals which depends on this clock also don't work (HDMI CEC for example). Make clocks property optional. If it is present, select external oscillator. If not, stay on internal. Signed-off-by: Jernej Skrabec Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20200308135849.106333-2-jernej.skrabec@siol.net Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 852f5f3b3592..415a20a936e4 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -250,19 +250,17 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, writel(reg, rtc->base + SUN6I_LOSC_CTRL); } - /* Switch to the external, more precise, oscillator */ - reg |= SUN6I_LOSC_CTRL_EXT_OSC; - if (rtc->data->has_losc_en) - reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + /* Switch to the external, more precise, oscillator, if present */ + if (of_get_property(node, "clocks", NULL)) { + reg |= SUN6I_LOSC_CTRL_EXT_OSC; + if (rtc->data->has_losc_en) + reg |= SUN6I_LOSC_CTRL_EXT_LOSC_EN; + } writel(reg, rtc->base + SUN6I_LOSC_CTRL); /* Yes, I know, this is ugly. */ sun6i_rtc = rtc; - /* Deal with old DTs */ - if (!of_get_property(node, "clocks", NULL)) - goto err; - /* Only read IOSC name from device tree if it is exported */ if (rtc->data->export_iosc) of_property_read_string_index(node, "clock-output-names", 2, @@ -279,11 +277,13 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, } parents[0] = clk_hw_get_name(rtc->int_osc); + /* If there is no external oscillator, this will be NULL and ... */ parents[1] = of_clk_get_parent_name(node, 0); rtc->hw.init = &init; init.parent_names = parents; + /* ... number of clock parents will be 1. */ init.num_parents = of_clk_get_parent_count(node) + 1; of_property_read_string_index(node, "clock-output-names", 0, &init.name); -- cgit v1.2.3 From eac1c3fc55f8744c0b2a4459f52f3761c1e588ab Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Mon, 9 Mar 2020 13:35:14 +0100 Subject: rtc: m48t35: remove SGI-IP27 kludge With the IOC3 MFD driver it's no longer necessary to special case SGI-IP27. Signed-off-by: Thomas Bogendoerfer Link: https://lore.kernel.org/r/20200309123514.15543-1-tsbogend@alpha.franken.de Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-m48t35.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c index e8194f1f01a8..92f19bf997b2 100644 --- a/drivers/rtc/rtc-m48t35.c +++ b/drivers/rtc/rtc-m48t35.c @@ -160,15 +160,10 @@ static int m48t35_probe(struct platform_device *pdev) return -ENOMEM; priv->size = resource_size(res); - /* - * kludge: remove the #ifndef after ioc3 resource - * conflicts are resolved - */ -#ifndef CONFIG_SGI_IP27 if (!devm_request_mem_region(&pdev->dev, res->start, priv->size, pdev->name)) return -EBUSY; -#endif + priv->baseaddr = res->start; priv->reg = devm_ioremap(&pdev->dev, priv->baseaddr, priv->size); if (!priv->reg) -- cgit v1.2.3 From 64823360a82939db212bc763443c990cbd99fa7c Mon Sep 17 00:00:00 2001 From: Ran Bi Date: Wed, 26 Feb 2020 13:13:01 +0800 Subject: rtc: add support for the MediaTek MT2712 RTC This add support for the MediaTek MT2712 RTC. It was SoC based RTC, but had different architecture compared with MT7622 RTC. Signed-off-by: Ran Bi Link: https://lore.kernel.org/r/20200226051303.22560-3-ran.bi@mediatek.com Link: https://lore.kernel.org/r/20200316104701.209293-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 10 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-mt2712.c | 421 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 432 insertions(+) create mode 100644 drivers/rtc/rtc-mt2712.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 777047620ec7..7d6cb60ee010 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1807,6 +1807,16 @@ config RTC_DRV_MOXART This driver can also be built as a module. If so, the module will be called rtc-moxart +config RTC_DRV_MT2712 + tristate "MediaTek MT2712 SoC based RTC" + depends on ARCH_MEDIATEK || COMPILE_TEST + help + This enables support for the real time clock built in the MediaTek + SoCs for MT2712. + + This drive can also be built as a module. If so, the module + will be called rtc-mt2712. + config RTC_DRV_MT6397 tristate "MediaTek PMIC based RTC" depends on MFD_MT6397 || (COMPILE_TEST && IRQ_DOMAIN) diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 4ac8f19fb631..6c3e93aa36dc 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -110,6 +110,7 @@ obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o +obj-$(CONFIG_RTC_DRV_MT2712) += rtc-mt2712.o obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o diff --git a/drivers/rtc/rtc-mt2712.c b/drivers/rtc/rtc-mt2712.c new file mode 100644 index 000000000000..62c20241426d --- /dev/null +++ b/drivers/rtc/rtc-mt2712.c @@ -0,0 +1,421 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 MediaTek Inc. + * Author: Ran Bi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MT2712_BBPU 0x0000 +#define MT2712_BBPU_CLRPKY BIT(4) +#define MT2712_BBPU_RELOAD BIT(5) +#define MT2712_BBPU_CBUSY BIT(6) +#define MT2712_BBPU_KEY (0x43 << 8) + +#define MT2712_IRQ_STA 0x0004 +#define MT2712_IRQ_STA_AL BIT(0) +#define MT2712_IRQ_STA_TC BIT(1) + +#define MT2712_IRQ_EN 0x0008 +#define MT2712_IRQ_EN_AL BIT(0) +#define MT2712_IRQ_EN_TC BIT(1) +#define MT2712_IRQ_EN_ONESHOT BIT(2) + +#define MT2712_CII_EN 0x000c + +#define MT2712_AL_MASK 0x0010 +#define MT2712_AL_MASK_DOW BIT(4) + +#define MT2712_TC_SEC 0x0014 +#define MT2712_TC_MIN 0x0018 +#define MT2712_TC_HOU 0x001c +#define MT2712_TC_DOM 0x0020 +#define MT2712_TC_DOW 0x0024 +#define MT2712_TC_MTH 0x0028 +#define MT2712_TC_YEA 0x002c + +#define MT2712_AL_SEC 0x0030 +#define MT2712_AL_MIN 0x0034 +#define MT2712_AL_HOU 0x0038 +#define MT2712_AL_DOM 0x003c +#define MT2712_AL_DOW 0x0040 +#define MT2712_AL_MTH 0x0044 +#define MT2712_AL_YEA 0x0048 + +#define MT2712_SEC_MASK 0x003f +#define MT2712_MIN_MASK 0x003f +#define MT2712_HOU_MASK 0x001f +#define MT2712_DOM_MASK 0x001f +#define MT2712_DOW_MASK 0x0007 +#define MT2712_MTH_MASK 0x000f +#define MT2712_YEA_MASK 0x007f + +#define MT2712_POWERKEY1 0x004c +#define MT2712_POWERKEY2 0x0050 +#define MT2712_POWERKEY1_KEY 0xa357 +#define MT2712_POWERKEY2_KEY 0x67d2 + +#define MT2712_CON0 0x005c +#define MT2712_CON1 0x0060 + +#define MT2712_PROT 0x0070 +#define MT2712_PROT_UNLOCK1 0x9136 +#define MT2712_PROT_UNLOCK2 0x586a + +#define MT2712_WRTGR 0x0078 + +#define MT2712_RTC_TIMESTAMP_END_2127 4985971199LL + +struct mt2712_rtc { + struct rtc_device *rtc; + void __iomem *base; + int irq; + u8 irq_wake_enabled; + u8 powerlost; +}; + +static inline u32 mt2712_readl(struct mt2712_rtc *mt2712_rtc, u32 reg) +{ + return readl(mt2712_rtc->base + reg); +} + +static inline void mt2712_writel(struct mt2712_rtc *mt2712_rtc, + u32 reg, u32 val) +{ + writel(val, mt2712_rtc->base + reg); +} + +static void mt2712_rtc_write_trigger(struct mt2712_rtc *mt2712_rtc) +{ + unsigned long timeout = jiffies + HZ / 10; + + mt2712_writel(mt2712_rtc, MT2712_WRTGR, 1); + while (1) { + if (!(mt2712_readl(mt2712_rtc, MT2712_BBPU) + & MT2712_BBPU_CBUSY)) + break; + + if (time_after(jiffies, timeout)) { + dev_err(&mt2712_rtc->rtc->dev, + "%s time out!\n", __func__); + break; + } + cpu_relax(); + } +} + +static void mt2712_rtc_writeif_unlock(struct mt2712_rtc *mt2712_rtc) +{ + mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK1); + mt2712_rtc_write_trigger(mt2712_rtc); + mt2712_writel(mt2712_rtc, MT2712_PROT, MT2712_PROT_UNLOCK2); + mt2712_rtc_write_trigger(mt2712_rtc); +} + +static irqreturn_t rtc_irq_handler_thread(int irq, void *data) +{ + struct mt2712_rtc *mt2712_rtc = data; + u16 irqsta; + + /* Clear interrupt */ + irqsta = mt2712_readl(mt2712_rtc, MT2712_IRQ_STA); + if (irqsta & MT2712_IRQ_STA_AL) { + rtc_update_irq(mt2712_rtc->rtc, 1, RTC_IRQF | RTC_AF); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} + +static void __mt2712_rtc_read_time(struct mt2712_rtc *mt2712_rtc, + struct rtc_time *tm, int *sec) +{ + tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) + & MT2712_SEC_MASK; + tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_TC_MIN) + & MT2712_MIN_MASK; + tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_TC_HOU) + & MT2712_HOU_MASK; + tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_TC_DOM) + & MT2712_DOM_MASK; + tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_TC_MTH) - 1) + & MT2712_MTH_MASK; + tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_TC_YEA) + 100) + & MT2712_YEA_MASK; + + *sec = mt2712_readl(mt2712_rtc, MT2712_TC_SEC) & MT2712_SEC_MASK; +} + +static int mt2712_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + int sec; + + if (mt2712_rtc->powerlost) + return -EINVAL; + + do { + __mt2712_rtc_read_time(mt2712_rtc, tm, &sec); + } while (sec < tm->tm_sec); /* SEC has carried */ + + return 0; +} + +static int mt2712_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + + mt2712_writel(mt2712_rtc, MT2712_TC_SEC, tm->tm_sec & MT2712_SEC_MASK); + mt2712_writel(mt2712_rtc, MT2712_TC_MIN, tm->tm_min & MT2712_MIN_MASK); + mt2712_writel(mt2712_rtc, MT2712_TC_HOU, tm->tm_hour & MT2712_HOU_MASK); + mt2712_writel(mt2712_rtc, MT2712_TC_DOM, tm->tm_mday & MT2712_DOM_MASK); + mt2712_writel(mt2712_rtc, MT2712_TC_MTH, + (tm->tm_mon + 1) & MT2712_MTH_MASK); + mt2712_writel(mt2712_rtc, MT2712_TC_YEA, + (tm->tm_year - 100) & MT2712_YEA_MASK); + + mt2712_rtc_write_trigger(mt2712_rtc); + + if (mt2712_rtc->powerlost) + mt2712_rtc->powerlost = false; + + return 0; +} + +static int mt2712_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + struct rtc_time *tm = &alm->time; + u16 irqen; + + irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN); + alm->enabled = !!(irqen & MT2712_IRQ_EN_AL); + + tm->tm_sec = mt2712_readl(mt2712_rtc, MT2712_AL_SEC) & MT2712_SEC_MASK; + tm->tm_min = mt2712_readl(mt2712_rtc, MT2712_AL_MIN) & MT2712_MIN_MASK; + tm->tm_hour = mt2712_readl(mt2712_rtc, MT2712_AL_HOU) & MT2712_HOU_MASK; + tm->tm_mday = mt2712_readl(mt2712_rtc, MT2712_AL_DOM) & MT2712_DOM_MASK; + tm->tm_mon = (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) - 1) + & MT2712_MTH_MASK; + tm->tm_year = (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + 100) + & MT2712_YEA_MASK; + + return 0; +} + +static int mt2712_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) +{ + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + u16 irqen; + + irqen = mt2712_readl(mt2712_rtc, MT2712_IRQ_EN); + if (enabled) + irqen |= MT2712_IRQ_EN_AL; + else + irqen &= ~MT2712_IRQ_EN_AL; + mt2712_writel(mt2712_rtc, MT2712_IRQ_EN, irqen); + mt2712_rtc_write_trigger(mt2712_rtc); + + return 0; +} + +static int mt2712_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + struct rtc_time *tm = &alm->time; + + dev_dbg(&mt2712_rtc->rtc->dev, "set al time: %ptR, alm en: %d\n", + tm, alm->enabled); + + mt2712_writel(mt2712_rtc, MT2712_AL_SEC, + (mt2712_readl(mt2712_rtc, MT2712_AL_SEC) + & ~(MT2712_SEC_MASK)) | (tm->tm_sec & MT2712_SEC_MASK)); + mt2712_writel(mt2712_rtc, MT2712_AL_MIN, + (mt2712_readl(mt2712_rtc, MT2712_AL_MIN) + & ~(MT2712_MIN_MASK)) | (tm->tm_min & MT2712_MIN_MASK)); + mt2712_writel(mt2712_rtc, MT2712_AL_HOU, + (mt2712_readl(mt2712_rtc, MT2712_AL_HOU) + & ~(MT2712_HOU_MASK)) | (tm->tm_hour & MT2712_HOU_MASK)); + mt2712_writel(mt2712_rtc, MT2712_AL_DOM, + (mt2712_readl(mt2712_rtc, MT2712_AL_DOM) + & ~(MT2712_DOM_MASK)) | (tm->tm_mday & MT2712_DOM_MASK)); + mt2712_writel(mt2712_rtc, MT2712_AL_MTH, + (mt2712_readl(mt2712_rtc, MT2712_AL_MTH) + & ~(MT2712_MTH_MASK)) + | ((tm->tm_mon + 1) & MT2712_MTH_MASK)); + mt2712_writel(mt2712_rtc, MT2712_AL_YEA, + (mt2712_readl(mt2712_rtc, MT2712_AL_YEA) + & ~(MT2712_YEA_MASK)) + | ((tm->tm_year - 100) & MT2712_YEA_MASK)); + + /* mask day of week */ + mt2712_writel(mt2712_rtc, MT2712_AL_MASK, MT2712_AL_MASK_DOW); + mt2712_rtc_write_trigger(mt2712_rtc); + + mt2712_rtc_alarm_irq_enable(dev, alm->enabled); + + return 0; +} + +/* Init RTC register */ +static void mt2712_rtc_hw_init(struct mt2712_rtc *mt2712_rtc) +{ + u32 p1, p2; + + mt2712_writel(mt2712_rtc, MT2712_BBPU, + MT2712_BBPU_KEY | MT2712_BBPU_RELOAD); + + mt2712_writel(mt2712_rtc, MT2712_CII_EN, 0); + mt2712_writel(mt2712_rtc, MT2712_AL_MASK, 0); + /* necessary before set MT2712_POWERKEY */ + mt2712_writel(mt2712_rtc, MT2712_CON0, 0x4848); + mt2712_writel(mt2712_rtc, MT2712_CON1, 0x0048); + + mt2712_rtc_write_trigger(mt2712_rtc); + + p1 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY1); + p2 = mt2712_readl(mt2712_rtc, MT2712_POWERKEY2); + if (p1 != MT2712_POWERKEY1_KEY || p2 != MT2712_POWERKEY2_KEY) { + mt2712_rtc->powerlost = true; + dev_dbg(&mt2712_rtc->rtc->dev, + "powerkey not set (lost power)\n"); + } else { + mt2712_rtc->powerlost = false; + } + + /* RTC need POWERKEY1/2 match, then goto normal work mode */ + mt2712_writel(mt2712_rtc, MT2712_POWERKEY1, MT2712_POWERKEY1_KEY); + mt2712_writel(mt2712_rtc, MT2712_POWERKEY2, MT2712_POWERKEY2_KEY); + mt2712_rtc_write_trigger(mt2712_rtc); + + mt2712_rtc_writeif_unlock(mt2712_rtc); +} + +static const struct rtc_class_ops mt2712_rtc_ops = { + .read_time = mt2712_rtc_read_time, + .set_time = mt2712_rtc_set_time, + .read_alarm = mt2712_rtc_read_alarm, + .set_alarm = mt2712_rtc_set_alarm, + .alarm_irq_enable = mt2712_rtc_alarm_irq_enable, +}; + +static int mt2712_rtc_probe(struct platform_device *pdev) +{ + struct resource *res; + struct mt2712_rtc *mt2712_rtc; + int ret; + + mt2712_rtc = devm_kzalloc(&pdev->dev, + sizeof(struct mt2712_rtc), GFP_KERNEL); + if (!mt2712_rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mt2712_rtc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mt2712_rtc->base)) + return PTR_ERR(mt2712_rtc->base); + + /* rtc hw init */ + mt2712_rtc_hw_init(mt2712_rtc); + + mt2712_rtc->irq = platform_get_irq(pdev, 0); + if (mt2712_rtc->irq < 0) { + dev_err(&pdev->dev, "No IRQ resource\n"); + return mt2712_rtc->irq; + } + + platform_set_drvdata(pdev, mt2712_rtc); + + mt2712_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(mt2712_rtc->rtc)) + return PTR_ERR(mt2712_rtc->rtc); + + ret = devm_request_threaded_irq(&pdev->dev, mt2712_rtc->irq, NULL, + rtc_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_LOW, + dev_name(&mt2712_rtc->rtc->dev), + mt2712_rtc); + if (ret) { + dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", + mt2712_rtc->irq, ret); + return ret; + } + + device_init_wakeup(&pdev->dev, true); + + mt2712_rtc->rtc->ops = &mt2712_rtc_ops; + mt2712_rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + mt2712_rtc->rtc->range_max = MT2712_RTC_TIMESTAMP_END_2127; + + ret = rtc_register_device(mt2712_rtc->rtc); + if (ret) { + dev_err(&pdev->dev, "register rtc device failed\n"); + return ret; + } + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int mt2712_rtc_suspend(struct device *dev) +{ + int wake_status = 0; + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) { + wake_status = enable_irq_wake(mt2712_rtc->irq); + if (!wake_status) + mt2712_rtc->irq_wake_enabled = true; + } + + return 0; +} + +static int mt2712_rtc_resume(struct device *dev) +{ + int wake_status = 0; + struct mt2712_rtc *mt2712_rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev) && mt2712_rtc->irq_wake_enabled) { + wake_status = disable_irq_wake(mt2712_rtc->irq); + if (!wake_status) + mt2712_rtc->irq_wake_enabled = false; + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mt2712_pm_ops, mt2712_rtc_suspend, + mt2712_rtc_resume); +#endif + +static const struct of_device_id mt2712_rtc_of_match[] = { + { .compatible = "mediatek,mt2712-rtc", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, mt2712_rtc_of_match); + +static struct platform_driver mt2712_rtc_driver = { + .driver = { + .name = "mt2712-rtc", + .of_match_table = mt2712_rtc_of_match, + .pm = &mt2712_pm_ops, + }, + .probe = mt2712_rtc_probe, +}; + +module_platform_driver(mt2712_rtc_driver); + +MODULE_DESCRIPTION("MediaTek MT2712 SoC based RTC Driver"); +MODULE_AUTHOR("Ran Bi "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 7863bd076b990f57076f2123337b67b5d5ccd190 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 13 Mar 2020 22:30:49 +0800 Subject: rtc: snvs: Use devm_add_action_or_reset() for calls to clk_disable_unprepare() Use devm_add_action_or_reset() for calls to clk_disable_unprepare(), which can simplify the error handling. Signed-off-by: Anson Huang Link: https://lore.kernel.org/r/1584109849-21402-1-git-send-email-Anson.Huang@nxp.com Link: https://lore.kernel.org/r/1584233264-26025-1-git-send-email-Anson.Huang@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-snvs.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 7630089a113c..35ee08aa7584 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -263,6 +263,12 @@ static const struct regmap_config snvs_rtc_config = { .reg_stride = 4, }; +static void snvs_rtc_action(void *data) +{ + if (data) + clk_disable_unprepare(data); +} + static int snvs_rtc_probe(struct platform_device *pdev) { struct snvs_rtc_data *data; @@ -313,6 +319,10 @@ static int snvs_rtc_probe(struct platform_device *pdev) } } + ret = devm_add_action_or_reset(&pdev->dev, snvs_rtc_action, data->clk); + if (ret) + return ret; + platform_set_drvdata(pdev, data); /* Initialize glitch detect */ @@ -325,7 +335,7 @@ static int snvs_rtc_probe(struct platform_device *pdev) ret = snvs_rtc_enable(data, true); if (ret) { dev_err(&pdev->dev, "failed to enable rtc %d\n", ret); - goto error_rtc_device_register; + return ret; } device_init_wakeup(&pdev->dev, true); @@ -338,24 +348,13 @@ static int snvs_rtc_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "failed to request irq %d: %d\n", data->irq, ret); - goto error_rtc_device_register; + return ret; } data->rtc->ops = &snvs_rtc_ops; data->rtc->range_max = U32_MAX; - ret = rtc_register_device(data->rtc); - if (ret) { - dev_err(&pdev->dev, "failed to register rtc: %d\n", ret); - goto error_rtc_device_register; - } - - return 0; -error_rtc_device_register: - if (data->clk) - clk_disable_unprepare(data->clk); - - return ret; + return rtc_register_device(data->rtc); } static int __maybe_unused snvs_rtc_suspend_noirq(struct device *dev) -- cgit v1.2.3 From 9cf4789e6e4673d0b2c96fa6bb0c35e81b43111a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:51 +0100 Subject: rtc: 88pm860x: fix possible race condition The RTC IRQ is requested before the struct rtc_device is allocated, this may lead to a NULL pointer dereference in the IRQ handler. To fix this issue, allocating the rtc_device struct before requesting the RTC IRQ using devm_rtc_allocate_device, and use rtc_register_device to register the RTC device. Also remove the unnecessary error message as the core already prints the info. Link: https://lore.kernel.org/r/20200311223956.51352-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 4743b16a8d84..1526402e126b 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -336,6 +336,10 @@ static int pm860x_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; dev_set_drvdata(&pdev->dev, info); + info->rtc_dev = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(info->rtc_dev)) + return PTR_ERR(info->rtc_dev); + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, rtc_update_handler, IRQF_ONESHOT, "rtc", info); @@ -377,13 +381,11 @@ static int pm860x_rtc_probe(struct platform_device *pdev) } } - info->rtc_dev = devm_rtc_device_register(&pdev->dev, "88pm860x-rtc", - &pm860x_rtc_ops, THIS_MODULE); - ret = PTR_ERR(info->rtc_dev); - if (IS_ERR(info->rtc_dev)) { - dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); + info->rtc_dev->ops = &pm860x_rtc_ops; + + ret = rtc_register_device(info->rtc_dev); + if (ret) return ret; - } /* * enable internal XO instead of internal 3.25MHz clock since it can -- cgit v1.2.3 From b773f2a97fc5d53c5e57cf37fd4029026d38ba55 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:52 +0100 Subject: rtc: 88pm860x: stop setting a default time It doesn't make sense to set the RTC to a default value at probe time. Let the core handle invalid date and time. Link: https://lore.kernel.org/r/20200311223956.51352-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 1526402e126b..d6aca28905e3 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -360,19 +360,6 @@ static int pm860x_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to read initial time.\n"); return ret; } - if ((tm.tm_year < 70) || (tm.tm_year > 138)) { - tm.tm_year = 70; - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - ret = pm860x_rtc_set_time(&pdev->dev, &tm); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to set initial time.\n"); - return ret; - } - } rtc_tm_to_time(&tm, &ticks); if (pm860x_rtc_dt_init(pdev, info)) { if (pdata && pdata->sync) { -- cgit v1.2.3 From 1c9fe6d6d2752cbca0b006355d0557cdf355b559 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:53 +0100 Subject: rtc: 88pm860x: stop calling unused callback pdata->sync is not defined by any platform, stop calling it. Link: https://lore.kernel.org/r/20200311223956.51352-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index d6aca28905e3..0abf2b194938 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -28,7 +28,6 @@ struct pm860x_rtc_info { int irq; int vrtc; - int (*sync)(unsigned int ticks); }; #define REG_VRTC_MEAS1 0x7D @@ -155,8 +154,6 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) pm860x_page_reg_write(info->i2c, REG2_DATA, (base >> 8) & 0xFF); pm860x_page_reg_write(info->i2c, REG3_DATA, base & 0xFF); - if (info->sync) - info->sync(ticks); return 0; } @@ -317,8 +314,6 @@ static int pm860x_rtc_probe(struct platform_device *pdev) struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); struct pm860x_rtc_pdata *pdata = NULL; struct pm860x_rtc_info *info; - struct rtc_time tm; - unsigned long ticks = 0; int ret; pdata = dev_get_platdata(&pdev->dev); @@ -355,18 +350,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev) pm860x_page_reg_write(info->i2c, REG2_ADDR, REG2_DATA); pm860x_page_reg_write(info->i2c, REG3_ADDR, REG3_DATA); - ret = pm860x_rtc_read_time(&pdev->dev, &tm); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to read initial time.\n"); - return ret; - } - rtc_tm_to_time(&tm, &ticks); - if (pm860x_rtc_dt_init(pdev, info)) { - if (pdata && pdata->sync) { - pdata->sync(ticks); - info->sync = pdata->sync; - } - } + pm860x_rtc_dt_init(pdev, info); info->rtc_dev->ops = &pm860x_rtc_ops; -- cgit v1.2.3 From a3e4937112cea362ebd813f9bf5e1a6b75cade1e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:54 +0100 Subject: rtc: 88pm860x: set range The 88pm860x RTC is a 32bit read only seconds counter with a 32bit offset. Link: https://lore.kernel.org/r/20200311223956.51352-4-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 0abf2b194938..f5933a08454c 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -353,6 +353,7 @@ static int pm860x_rtc_probe(struct platform_device *pdev) pm860x_rtc_dt_init(pdev, info); info->rtc_dev->ops = &pm860x_rtc_ops; + info->rtc_dev->range_max = U32_MAX; ret = rtc_register_device(info->rtc_dev); if (ret) -- cgit v1.2.3 From 3b45cc522e5bb68ff4b0572b517f3aa0789a26c2 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:55 +0100 Subject: rtc: 88pm860x: stop mangling alarm time The RTC core always passes a valid alarm time there is no need to modify it. Link: https://lore.kernel.org/r/20200311223956.51352-5-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 41 +---------------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index f5933a08454c..e0b18227514b 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -75,33 +75,6 @@ static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -/* - * Calculate the next alarm time given the requested alarm time mask - * and the current time. - */ -static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, - struct rtc_time *alrm) -{ - unsigned long next_time; - unsigned long now_time; - - next->tm_year = now->tm_year; - next->tm_mon = now->tm_mon; - next->tm_mday = now->tm_mday; - next->tm_hour = alrm->tm_hour; - next->tm_min = alrm->tm_min; - next->tm_sec = alrm->tm_sec; - - rtc_tm_to_time(now, &now_time); - rtc_tm_to_time(next, &next_time); - - if (next_time < now_time) { - /* Advance one day */ - next_time += 60 * 60 * 24; - rtc_time_to_tm(next_time, next); - } -} - static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct pm860x_rtc_info *info = dev_get_drvdata(dev); @@ -187,7 +160,6 @@ static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct pm860x_rtc_info *info = dev_get_drvdata(dev); - struct rtc_time now_tm, alarm_tm; unsigned long ticks, base, data; unsigned char buf[8]; int mask; @@ -200,18 +172,7 @@ static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) base = ((unsigned long)buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; - /* load 32-bit read-only counter */ - pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); - data = ((unsigned long)buf[3] << 24) | (buf[2] << 16) | - (buf[1] << 8) | buf[0]; - ticks = base + data; - dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", - base, data, ticks); - - rtc_time_to_tm(ticks, &now_tm); - rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time); - /* get new ticks for alarm in 24 hours */ - rtc_tm_to_time(&alarm_tm, &ticks); + rtc_tm_to_time(&alrm->time, &ticks); data = ticks - base; buf[0] = data & 0xff; -- cgit v1.2.3 From b2a2aa63f9f1b87b0e6cac0eead3962bb09ee16c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Wed, 11 Mar 2020 23:39:56 +0100 Subject: rtc: 88pm860x: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Link: https://lore.kernel.org/r/20200311223956.51352-6-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index e0b18227514b..88bda3e072d8 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -95,7 +95,7 @@ static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm) dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", base, data, ticks); - rtc_time_to_tm(ticks, tm); + rtc_time64_to_tm(ticks, tm); return 0; } @@ -112,7 +112,7 @@ static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm) 1900 + tm->tm_year); return -EINVAL; } - rtc_tm_to_time(tm, &ticks); + ticks = rtc_tm_to_time64(tm); /* load 32-bit read-only counter */ pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf); @@ -150,7 +150,7 @@ static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n", base, data, ticks); - rtc_time_to_tm(ticks, &alrm->time); + rtc_time64_to_tm(ticks, &alrm->time); ret = pm860x_reg_read(info->i2c, PM8607_RTC1); alrm->enabled = (ret & ALARM_EN) ? 1 : 0; alrm->pending = (ret & (ALARM | ALARM_WAKEUP)) ? 1 : 0; @@ -172,7 +172,7 @@ static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) base = ((unsigned long)buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7]; - rtc_tm_to_time(&alrm->time, &ticks); + ticks = rtc_tm_to_time64(&alrm->time); data = ticks - base; buf[0] = data & 0xff; -- cgit v1.2.3 From ccf1441db9ca84fb2803a361964a0ffc4165c2d8 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 16 Mar 2020 11:25:37 +0100 Subject: rtc: 88pm860x: remove platform data support There is no users of the rtc platform data left, remove its support. Link: https://lore.kernel.org/r/20200316102537.180398-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-88pm860x.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c index 88bda3e072d8..cc9b14ef90f1 100644 --- a/drivers/rtc/rtc-88pm860x.c +++ b/drivers/rtc/rtc-88pm860x.c @@ -267,18 +267,15 @@ static int pm860x_rtc_dt_init(struct platform_device *pdev, return 0; } #else -#define pm860x_rtc_dt_init(x, y) (-1) +#define pm860x_rtc_dt_init(x, y) do { } while (0) #endif static int pm860x_rtc_probe(struct platform_device *pdev) { struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); - struct pm860x_rtc_pdata *pdata = NULL; struct pm860x_rtc_info *info; int ret; - pdata = dev_get_platdata(&pdev->dev); - info = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_rtc_info), GFP_KERNEL); if (!info) @@ -328,12 +325,6 @@ static int pm860x_rtc_probe(struct platform_device *pdev) #ifdef VRTC_CALIBRATION /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ - if (pm860x_rtc_dt_init(pdev, info)) { - if (pdata && pdata->vrtc) - info->vrtc = pdata->vrtc & 0x3; - else - info->vrtc = 1; - } pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); /* calibrate VRTC */ -- cgit v1.2.3 From 30a790653d8ac46d3116abe99ba745a7b0c27b8b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 17 Mar 2020 15:34:21 +0100 Subject: rtc: mt2712: fix build without PM_SLEEP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix this build error when PM_SLEEP is not selected: drivers/rtc/rtc-mt2712.c:412:10: error: ‘mt2712_pm_ops’ undeclared here (not in a function); did you mean ‘mt2712_rtc_ops’? 412 | .pm = &mt2712_pm_ops, | ^~~~~~~~~~~~~ Link: https://lore.kernel.org/r/20200317143421.9551-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mt2712.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mt2712.c b/drivers/rtc/rtc-mt2712.c index 62c20241426d..581b8731fb8a 100644 --- a/drivers/rtc/rtc-mt2712.c +++ b/drivers/rtc/rtc-mt2712.c @@ -409,7 +409,9 @@ static struct platform_driver mt2712_rtc_driver = { .driver = { .name = "mt2712-rtc", .of_match_table = mt2712_rtc_of_match, +#ifdef CONFIG_PM_SLEEP .pm = &mt2712_pm_ops, +#endif }, .probe = mt2712_rtc_probe, }; -- cgit v1.2.3 From df11b323b16fce74d32571c2f80074df41df002d Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Fri, 7 Feb 2020 16:18:11 +1300 Subject: rtc: ds1307: handle oscillator failure flags for ds1388 variant The FLAG register is at a different location to the other supported RTCs so this requires an extra case in the existing switch statement. Signed-off-by: Chris Packham Link: https://lore.kernel.org/r/20200207031812.14424-2-chris.packham@alliedtelesis.co.nz Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 1f7e8aefc1eb..31a38d468378 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -144,6 +144,8 @@ enum ds_type { # define M41TXX_BIT_CALIB_SIGN BIT(5) # define M41TXX_M_CALIBRATION GENMASK(4, 0) +#define DS1388_REG_FLAG 0x0b +# define DS1388_BIT_OSF BIT(7) /* negative offset step is -2.034ppm */ #define M41TXX_NEG_OFFSET_STEP_PPB 2034 /* positive offset step is +4.068ppm */ @@ -252,6 +254,13 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t) if (tmp & DS1340_BIT_OSF) return -EINVAL; break; + case ds_1388: + ret = regmap_read(ds1307->regmap, DS1388_REG_FLAG, &tmp); + if (ret) + return ret; + if (tmp & DS1388_BIT_OSF) + return -EINVAL; + break; case mcp794xx: if (!(tmp & MCP794XX_BIT_ST)) return -EINVAL; -- cgit v1.2.3 From fdc9f0eace99b288d5ef5cc7489699bf7b2d9e36 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Mon, 16 Mar 2020 17:09:45 +0800 Subject: rtc: mxc: Use devm_add_action_or_reset() for calls to clk_disable_unprepare() Use devm_add_action_or_reset() for calls to clk_disable_unprepare(), which can simplify the error handling, and .remove callback can be dropped. Signed-off-by: Anson Huang Link: https://lore.kernel.org/r/1584349785-27042-1-git-send-email-Anson.Huang@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-mxc.c | 46 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 902d57dcd0d4..a8cfbde048f4 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -307,6 +307,14 @@ static const struct rtc_class_ops mxc_rtc_ops = { .alarm_irq_enable = mxc_rtc_alarm_irq_enable, }; +static void mxc_rtc_action(void *p) +{ + struct rtc_plat_data *pdata = p; + + clk_disable_unprepare(pdata->clk_ref); + clk_disable_unprepare(pdata->clk_ipg); +} + static int mxc_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; @@ -366,14 +374,20 @@ static int mxc_rtc_probe(struct platform_device *pdev) pdata->clk_ref = devm_clk_get(&pdev->dev, "ref"); if (IS_ERR(pdata->clk_ref)) { + clk_disable_unprepare(pdata->clk_ipg); dev_err(&pdev->dev, "unable to get ref clock!\n"); - ret = PTR_ERR(pdata->clk_ref); - goto exit_put_clk_ipg; + return PTR_ERR(pdata->clk_ref); } ret = clk_prepare_enable(pdata->clk_ref); + if (ret) { + clk_disable_unprepare(pdata->clk_ipg); + return ret; + } + + ret = devm_add_action_or_reset(&pdev->dev, mxc_rtc_action, pdata); if (ret) - goto exit_put_clk_ipg; + return ret; rate = clk_get_rate(pdata->clk_ref); @@ -385,16 +399,14 @@ static int mxc_rtc_probe(struct platform_device *pdev) reg = RTC_INPUT_CLK_38400HZ; else { dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); - ret = -EINVAL; - goto exit_put_clk_ref; + return -EINVAL; } reg |= RTC_ENABLE_BIT; writew(reg, (pdata->ioaddr + RTC_RTCCTL)); if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { dev_err(&pdev->dev, "hardware module can't be enabled!\n"); - ret = -EIO; - goto exit_put_clk_ref; + return -EIO; } platform_set_drvdata(pdev, pdata); @@ -417,29 +429,10 @@ static int mxc_rtc_probe(struct platform_device *pdev) } ret = rtc_register_device(rtc); - if (ret) - goto exit_put_clk_ref; - - return 0; - -exit_put_clk_ref: - clk_disable_unprepare(pdata->clk_ref); -exit_put_clk_ipg: - clk_disable_unprepare(pdata->clk_ipg); return ret; } -static int mxc_rtc_remove(struct platform_device *pdev) -{ - struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - - clk_disable_unprepare(pdata->clk_ref); - clk_disable_unprepare(pdata->clk_ipg); - - return 0; -} - static struct platform_driver mxc_rtc_driver = { .driver = { .name = "mxc_rtc", @@ -447,7 +440,6 @@ static struct platform_driver mxc_rtc_driver = { }, .id_table = imx_rtc_devtype, .probe = mxc_rtc_probe, - .remove = mxc_rtc_remove, }; module_platform_driver(mxc_rtc_driver) -- cgit v1.2.3 From 929a3270488956316214d70cd4e2ba3fa56ffe31 Mon Sep 17 00:00:00 2001 From: Peng Ma Date: Wed, 18 Mar 2020 10:53:54 +0800 Subject: rtc: fsl-ftm-alarm: enable acpi support This patch enables ACPI support in Rtc Flex timer driver. Signed-off-by: Peng Ma Link: https://lore.kernel.org/r/20200318025354.6447-1-peng.ma@nxp.com Link: https://lore.kernel.org/r/20200323072956.38263-1-peng.ma@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-fsl-ftm-alarm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c index 9e6e994cce99..0f4142b35f38 100644 --- a/drivers/rtc/rtc-fsl-ftm-alarm.c +++ b/drivers/rtc/rtc-fsl-ftm-alarm.c @@ -20,6 +20,7 @@ #include #include #include +#include #define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_MASK_SHIFT) @@ -242,7 +243,6 @@ static const struct rtc_class_ops ftm_rtc_ops = { static int ftm_rtc_probe(struct platform_device *pdev) { - struct device_node *np = pdev->dev.of_node; int irq; int ret; struct ftm_rtc *rtc; @@ -265,10 +265,10 @@ static int ftm_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->base); } - irq = irq_of_parse_and_map(np, 0); - if (irq <= 0) { - dev_err(&pdev->dev, "unable to get IRQ from DT, %d\n", irq); - return -EINVAL; + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "can't get irq number\n"); + return irq; } ret = devm_request_irq(&pdev->dev, irq, ftm_rtc_alarm_interrupt, @@ -278,7 +278,9 @@ static int ftm_rtc_probe(struct platform_device *pdev) return ret; } - rtc->big_endian = of_property_read_bool(np, "big-endian"); + rtc->big_endian = + device_property_read_bool(&pdev->dev, "big-endian"); + rtc->alarm_freq = (u32)FIXED_FREQ_CLK / (u32)MAX_FREQ_DIV; rtc->rtc_dev->ops = &ftm_rtc_ops; @@ -305,11 +307,18 @@ static const struct of_device_id ftm_rtc_match[] = { { }, }; +static const struct acpi_device_id ftm_imx_acpi_ids[] = { + {"NXP0011",}, + { } +}; +MODULE_DEVICE_TABLE(acpi, ftm_imx_acpi_ids); + static struct platform_driver ftm_rtc_driver = { .probe = ftm_rtc_probe, .driver = { .name = "ftm-alarm", .of_match_table = ftm_rtc_match, + .acpi_match_table = ACPI_PTR(ftm_imx_acpi_ids), }, }; -- cgit v1.2.3 From c05a31f4d1de8f49f66f499e67da9c3d745c4f19 Mon Sep 17 00:00:00 2001 From: Corentin Labbe Date: Wed, 18 Mar 2020 15:26:49 +0000 Subject: rtc: max8907: add missing select REGMAP_IRQ I have hit the following build error: armv7a-hardfloat-linux-gnueabi-ld: drivers/rtc/rtc-max8907.o: in function `max8907_rtc_probe': rtc-max8907.c:(.text+0x400): undefined reference to `regmap_irq_get_virq' max8907 should select REGMAP_IRQ Fixes: 94c01ab6d7544 ("rtc: add MAX8907 RTC driver") Cc: stable Signed-off-by: Corentin Labbe Link: https://lore.kernel.org/r/1584545209-20433-1-git-send-email-clabbe@baylibre.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 7d6cb60ee010..6c99156cbe57 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -327,6 +327,7 @@ config RTC_DRV_MAX6900 config RTC_DRV_MAX8907 tristate "Maxim MAX8907" depends on MFD_MAX8907 || COMPILE_TEST + select REGMAP_IRQ help If you say yes here you will get support for the RTC of Maxim MAX8907 PMIC. -- cgit v1.2.3 From 6e7af45102994dca6941720c2207f081f8f26adc Mon Sep 17 00:00:00 2001 From: Keyur Patel Date: Sat, 21 Mar 2020 14:08:37 -0400 Subject: rtc: bd70528: Avoid double error messaging when IRQ absent Since the commit 7723f4c ("driver core: platform: Add an error message to platform_get_irq*()") platform_get_irq() started issuing an error message. Thus, there is no need to have the same in the driver. Signed-off-by: Keyur Patel Link: https://lore.kernel.org/r/20200321180838.12729-1-iamkeyur96@gmail.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-bd70528.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c index bbbb1f07c91f..4492b770422c 100644 --- a/drivers/rtc/rtc-bd70528.c +++ b/drivers/rtc/rtc-bd70528.c @@ -542,10 +542,8 @@ static int bd70528_probe(struct platform_device *pdev) irq = platform_get_irq_byname(pdev, irq_name); - if (irq < 0) { - dev_err(&pdev->dev, "Failed to get irq\n"); + if (irq < 0) return irq; - } platform_set_drvdata(pdev, bd_rtc); -- cgit v1.2.3 From 4828a82e29eb77628526fd6b92d528c2f724cb32 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Sat, 21 Mar 2020 21:37:37 +0100 Subject: rtc: omap: drop unused dt-bindings header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The definitons in the dt-binding's gpio header only contains some constants to be used in device trees. It is not relevant for rtc-omap (as the gpio API hides the details) and in fact unused so it can just be dropped. Signed-off-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20200321203737.29850-1-uwe@kleine-koenig.org Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-omap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index d4ed20fb3194..c20fc7937dfa 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c @@ -9,7 +9,6 @@ * Copyright (C) 2014 Johan Hovold */ -#include #include #include #include -- cgit v1.2.3 From 34ce29774dadc24ac1a529c562c325db2b77c7b4 Mon Sep 17 00:00:00 2001 From: 韩科才 Date: Sat, 21 Mar 2020 19:50:17 +0800 Subject: rtc: pm8xxx: clear alarm register when alarm is not enabled Clear alarm register when alarm is not enabled otherwise the consumer may still start alarm timer if it find the alarm register is not zero. Signed-off-by: hankecai Link: https://lore.kernel.org/r/APoAZgAaCEiRpKG6PlzreaqE.1.1584791417367.Hmail.hankecai@vivo.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pm8xxx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pm8xxx.c b/drivers/rtc/rtc-pm8xxx.c index e3d9abb2134e..b45ee2cb2c04 100644 --- a/drivers/rtc/rtc-pm8xxx.c +++ b/drivers/rtc/rtc-pm8xxx.c @@ -295,6 +295,7 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; unsigned int ctrl_reg; + u8 value[NUM_8_BIT_RTC_REGS] = {0}; spin_lock_irqsave(&rtc_dd->ctrl_reg_lock, irq_flags); @@ -313,6 +314,16 @@ static int pm8xxx_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) goto rtc_rw_fail; } + /* Clear Alarm register */ + if (!enable) { + rc = regmap_bulk_write(rtc_dd->regmap, regs->alarm_rw, value, + sizeof(value)); + if (rc) { + dev_err(dev, "Clear RTC ALARM register failed\n"); + goto rtc_rw_fail; + } + } + rtc_rw_fail: spin_unlock_irqrestore(&rtc_dd->ctrl_reg_lock, irq_flags); return rc; -- cgit v1.2.3 From f9b2a4d6a5f18e0aaf715206a056565c56889d9f Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Wed, 6 Nov 2019 11:46:25 -0800 Subject: rtc: class: support hctosys from modular RTC drivers Due to distribution constraints it may not be possible to statically compile the required RTC driver into the kernel. Expand RTC_HCTOSYS support to cover all RTC devices (statically compiled or not) by checking at the end of RTC device registration whether the time should be synced. Signed-off-by: Steve Muckle Link: https://lore.kernel.org/r/20191106194625.116692-1-smuckle@google.com Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 3 --- drivers/rtc/Makefile | 1 - drivers/rtc/class.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ drivers/rtc/hctosys.c | 69 --------------------------------------------------- 4 files changed, 61 insertions(+), 73 deletions(-) delete mode 100644 drivers/rtc/hctosys.c (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 6c99156cbe57..417fc6ec9338 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -41,9 +41,6 @@ config RTC_HCTOSYS_DEVICE device should record time in UTC, since the kernel won't do timezone correction. - The driver for this RTC device must be loaded before late_initcall - functions run, so it must usually be statically linked. - This clock should be battery-backed, so that it reads the correct time when the system boots from a power-off state. Otherwise, your system will need an external clock source (like an NTP server). diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 6c3e93aa36dc..8642d6f7560d 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -6,7 +6,6 @@ ccflags-$(CONFIG_RTC_DEBUG) := -DDEBUG obj-$(CONFIG_RTC_LIB) += lib.o -obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o obj-$(CONFIG_RTC_SYSTOHC) += systohc.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o obj-$(CONFIG_RTC_MC146818_LIB) += rtc-mc146818-lib.o diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 9458e6d6686a..8793b2b8cf9d 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -34,6 +34,62 @@ static void rtc_device_release(struct device *dev) #ifdef CONFIG_RTC_HCTOSYS_DEVICE /* Result of the last RTC to system clock attempt. */ int rtc_hctosys_ret = -ENODEV; + +/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary + * whether it stores the most close value or the value with partial + * seconds truncated. However, it is important that we use it to store + * the truncated value. This is because otherwise it is necessary, + * in an rtc sync function, to read both xtime.tv_sec and + * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read + * of >32bits is not possible. So storing the most close value would + * slow down the sync API. So here we have the truncated value and + * the best guess is to add 0.5s. + */ + +static int rtc_hctosys(void) +{ + int err = -ENODEV; + struct rtc_time tm; + struct timespec64 tv64 = { + .tv_nsec = NSEC_PER_SEC >> 1, + }; + struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + + if (!rtc) { + pr_info("unable to open rtc device (%s)\n", + CONFIG_RTC_HCTOSYS_DEVICE); + goto err_open; + } + + err = rtc_read_time(rtc, &tm); + if (err) { + dev_err(rtc->dev.parent, + "hctosys: unable to read the hardware clock\n"); + goto err_read; + } + + tv64.tv_sec = rtc_tm_to_time64(&tm); + +#if BITS_PER_LONG == 32 + if (tv64.tv_sec > INT_MAX) { + err = -ERANGE; + goto err_read; + } +#endif + + err = do_settimeofday64(&tv64); + + dev_info(rtc->dev.parent, "setting system clock to %ptR UTC (%lld)\n", + &tm, (long long)tv64.tv_sec); + +err_read: + rtc_class_close(rtc); + +err_open: + rtc_hctosys_ret = err; + + return err; +} #endif #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_RTC_HCTOSYS_DEVICE) @@ -375,6 +431,11 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) dev_info(rtc->dev.parent, "registered as %s\n", dev_name(&rtc->dev)); +#ifdef CONFIG_RTC_HCTOSYS_DEVICE + if (!strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE)) + rtc_hctosys(); +#endif + return 0; } EXPORT_SYMBOL_GPL(__rtc_register_device); diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c deleted file mode 100644 index a74d0d890600..000000000000 --- a/drivers/rtc/hctosys.c +++ /dev/null @@ -1,69 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * RTC subsystem, initialize system time on startup - * - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include - -/* IMPORTANT: the RTC only stores whole seconds. It is arbitrary - * whether it stores the most close value or the value with partial - * seconds truncated. However, it is important that we use it to store - * the truncated value. This is because otherwise it is necessary, - * in an rtc sync function, to read both xtime.tv_sec and - * xtime.tv_nsec. On some processors (i.e. ARM), an atomic read - * of >32bits is not possible. So storing the most close value would - * slow down the sync API. So here we have the truncated value and - * the best guess is to add 0.5s. - */ - -static int __init rtc_hctosys(void) -{ - int err = -ENODEV; - struct rtc_time tm; - struct timespec64 tv64 = { - .tv_nsec = NSEC_PER_SEC >> 1, - }; - struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - - if (!rtc) { - pr_info("unable to open rtc device (%s)\n", - CONFIG_RTC_HCTOSYS_DEVICE); - goto err_open; - } - - err = rtc_read_time(rtc, &tm); - if (err) { - dev_err(rtc->dev.parent, - "hctosys: unable to read the hardware clock\n"); - goto err_read; - } - - tv64.tv_sec = rtc_tm_to_time64(&tm); - -#if BITS_PER_LONG == 32 - if (tv64.tv_sec > INT_MAX) { - err = -ERANGE; - goto err_read; - } -#endif - - err = do_settimeofday64(&tv64); - - dev_info(rtc->dev.parent, "setting system clock to %ptR UTC (%lld)\n", - &tm, (long long)tv64.tv_sec); - -err_read: - rtc_class_close(rtc); - -err_open: - rtc_hctosys_ret = err; - - return err; -} - -late_initcall(rtc_hctosys); -- cgit v1.2.3 From 5840748520be19ea97ffdb80e5aa313c6ef60575 Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 11 Mar 2020 19:23:16 +0100 Subject: rtc: jz4740: Add support for JZ4760 SoC The WENR feature (set a magic value to enable RTC registers read-write) first appeared on the JZ4760; the JZ4780 came much later. Since it would be dangerous to specify a newer SoC's compatible string as the fallback of an older SoC's compatible string, we add support for the "ingenic,jz4760-rtc" compatible string in the driver. This will permit to support the JZ4770 by having: compatible = "ingenic,jz4770-rtc", "ingenic,jz4760-rtc"; Instead of doing: compatible = "ingenic,jz4770-rtc", "ingenic,jz4780-rtc"; Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200311182318.22154-1-paul@crapouillou.net Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-jz4740.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index 18023e472cbc..d764cd525c9a 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -46,6 +46,7 @@ enum jz4740_rtc_type { ID_JZ4740, + ID_JZ4760, ID_JZ4780, }; @@ -106,7 +107,7 @@ static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg, { int ret = 0; - if (rtc->type >= ID_JZ4780) + if (rtc->type >= ID_JZ4760) ret = jz4780_rtc_enable_write(rtc); if (ret == 0) ret = jz4740_rtc_wait_write_ready(rtc); @@ -298,6 +299,7 @@ static void jz4740_rtc_power_off(void) static const struct of_device_id jz4740_rtc_of_match[] = { { .compatible = "ingenic,jz4740-rtc", .data = (void *)ID_JZ4740 }, + { .compatible = "ingenic,jz4760-rtc", .data = (void *)ID_JZ4760 }, { .compatible = "ingenic,jz4780-rtc", .data = (void *)ID_JZ4780 }, {}, }; -- cgit v1.2.3 From 91b298f5dc95e632bd17e325fc32caad19d3f27d Mon Sep 17 00:00:00 2001 From: Paul Cercueil Date: Wed, 11 Mar 2020 19:23:17 +0100 Subject: rtc: jz4740: Rename vendor-specific DT properties These properties are never set anywhere within any of the upstream devicetree files, so I assume I'm not breaking the ABI with this change. Rename vendor-specific DT properties to have the 'ingenic,' prefix, which they should have had from the start. Signed-off-by: Paul Cercueil Link: https://lore.kernel.org/r/20200311182318.22154-2-paul@crapouillou.net Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-jz4740.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-jz4740.c b/drivers/rtc/rtc-jz4740.c index d764cd525c9a..e4c719085c31 100644 --- a/drivers/rtc/rtc-jz4740.c +++ b/drivers/rtc/rtc-jz4740.c @@ -374,13 +374,14 @@ static int jz4740_rtc_probe(struct platform_device *pdev) if (!pm_power_off) { /* Default: 60ms */ rtc->reset_pin_assert_time = 60; - of_property_read_u32(np, "reset-pin-assert-time-ms", + of_property_read_u32(np, + "ingenic,reset-pin-assert-time-ms", &rtc->reset_pin_assert_time); /* Default: 100ms */ rtc->min_wakeup_pin_assert_time = 100; of_property_read_u32(np, - "min-wakeup-pin-assert-time-ms", + "ingenic,min-wakeup-pin-assert-time-ms", &rtc->min_wakeup_pin_assert_time); dev_for_power_off = &pdev->dev; -- cgit v1.2.3 From 5614a4a3ca0e8806e144419536f52df419caa14f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 23 Mar 2020 22:30:39 +0100 Subject: rtc: class: avoid unnecessary lookup in hctosys rtc_hctosys is only called when the relevant RTC is found, avoid looking it up while we already have a pinter to the proper struct rtc_device. Link: https://lore.kernel.org/r/20200323213039.297458-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/class.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 8793b2b8cf9d..03d6516941a8 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -46,20 +46,13 @@ int rtc_hctosys_ret = -ENODEV; * the best guess is to add 0.5s. */ -static int rtc_hctosys(void) +static void rtc_hctosys(struct rtc_device *rtc) { int err = -ENODEV; struct rtc_time tm; struct timespec64 tv64 = { .tv_nsec = NSEC_PER_SEC >> 1, }; - struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - - if (!rtc) { - pr_info("unable to open rtc device (%s)\n", - CONFIG_RTC_HCTOSYS_DEVICE); - goto err_open; - } err = rtc_read_time(rtc, &tm); if (err) { @@ -83,12 +76,7 @@ static int rtc_hctosys(void) &tm, (long long)tv64.tv_sec); err_read: - rtc_class_close(rtc); - -err_open: rtc_hctosys_ret = err; - - return err; } #endif @@ -433,7 +421,7 @@ int __rtc_register_device(struct module *owner, struct rtc_device *rtc) #ifdef CONFIG_RTC_HCTOSYS_DEVICE if (!strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE)) - rtc_hctosys(); + rtc_hctosys(rtc); #endif return 0; -- cgit v1.2.3 From 8c229ab6048b796aa8197d64eb2f9182d828ff61 Mon Sep 17 00:00:00 2001 From: Michael McCormick Date: Fri, 24 Jan 2020 14:52:38 +1300 Subject: rtc: pcf85063: Add pcf85063 clkout control to common clock framework The PCF85063 has a configurable clock output signal. Add support for it using in the CCF. Signed-off-by: Michael McCormick Link: https://lore.kernel.org/r/20200124015239.24662-1-michael.mccormick@enatel.net Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-pcf85063.c | 157 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 1db17ba1fc64..7a87f461bec8 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -9,6 +9,7 @@ * Copyright (C) 2019 Micro Crystal AG * Author: Alexandre Belloni */ +#include #include #include #include @@ -44,6 +45,10 @@ #define PCF85063_OFFSET_STEP0 4340 #define PCF85063_OFFSET_STEP1 4069 +#define PCF85063_REG_CLKO_F_MASK 0x07 /* frequency mask */ +#define PCF85063_REG_CLKO_F_32768HZ 0x00 +#define PCF85063_REG_CLKO_F_OFF 0x07 + #define PCF85063_REG_RAM 0x03 #define PCF85063_REG_SC 0x04 /* datetime */ @@ -61,6 +66,9 @@ struct pcf85063_config { struct pcf85063 { struct rtc_device *rtc; struct regmap *regmap; +#ifdef CONFIG_COMMON_CLK + struct clk_hw clkout_hw; +#endif }; static int pcf85063_rtc_read_time(struct device *dev, struct rtc_time *tm) @@ -357,6 +365,150 @@ static int pcf85063_load_capacitance(struct pcf85063 *pcf85063, PCF85063_REG_CTRL1_CAP_SEL, reg); } +#ifdef CONFIG_COMMON_CLK +/* + * Handling of the clkout + */ + +#define clkout_hw_to_pcf85063(_hw) container_of(_hw, struct pcf85063, clkout_hw) + +static int clkout_rates[] = { + 32768, + 16384, + 8192, + 4096, + 2048, + 1024, + 1, + 0 +}; + +static unsigned long pcf85063_clkout_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pcf85063 *pcf85063 = clkout_hw_to_pcf85063(hw); + unsigned int buf; + int ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf); + + if (ret < 0) + return 0; + + buf &= PCF85063_REG_CLKO_F_MASK; + return clkout_rates[buf]; +} + +static long pcf85063_clkout_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] <= rate) + return clkout_rates[i]; + + return 0; +} + +static int pcf85063_clkout_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct pcf85063 *pcf85063 = clkout_hw_to_pcf85063(hw); + int i; + + for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) + if (clkout_rates[i] == rate) + return regmap_update_bits(pcf85063->regmap, + PCF85063_REG_CTRL2, + PCF85063_REG_CLKO_F_MASK, i); + + return -EINVAL; +} + +static int pcf85063_clkout_control(struct clk_hw *hw, bool enable) +{ + struct pcf85063 *pcf85063 = clkout_hw_to_pcf85063(hw); + unsigned int buf; + int ret; + + ret = regmap_read(pcf85063->regmap, PCF85063_REG_OFFSET, &buf); + if (ret < 0) + return ret; + buf &= PCF85063_REG_CLKO_F_MASK; + + if (enable) { + if (buf == PCF85063_REG_CLKO_F_OFF) + buf = PCF85063_REG_CLKO_F_32768HZ; + else + return 0; + } else { + if (buf != PCF85063_REG_CLKO_F_OFF) + buf = PCF85063_REG_CLKO_F_OFF; + else + return 0; + } + + return regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL2, + PCF85063_REG_CLKO_F_MASK, buf); +} + +static int pcf85063_clkout_prepare(struct clk_hw *hw) +{ + return pcf85063_clkout_control(hw, 1); +} + +static void pcf85063_clkout_unprepare(struct clk_hw *hw) +{ + pcf85063_clkout_control(hw, 0); +} + +static int pcf85063_clkout_is_prepared(struct clk_hw *hw) +{ + struct pcf85063 *pcf85063 = clkout_hw_to_pcf85063(hw); + unsigned int buf; + int ret = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL2, &buf); + + if (ret < 0) + return 0; + + return (buf & PCF85063_REG_CLKO_F_MASK) != PCF85063_REG_CLKO_F_OFF; +} + +static const struct clk_ops pcf85063_clkout_ops = { + .prepare = pcf85063_clkout_prepare, + .unprepare = pcf85063_clkout_unprepare, + .is_prepared = pcf85063_clkout_is_prepared, + .recalc_rate = pcf85063_clkout_recalc_rate, + .round_rate = pcf85063_clkout_round_rate, + .set_rate = pcf85063_clkout_set_rate, +}; + +static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063) +{ + struct clk *clk; + struct clk_init_data init; + + init.name = "pcf85063-clkout"; + init.ops = &pcf85063_clkout_ops; + init.flags = 0; + init.parent_names = NULL; + init.num_parents = 0; + pcf85063->clkout_hw.init = &init; + + /* optional override of the clockname */ + of_property_read_string(pcf85063->rtc->dev.of_node, + "clock-output-names", &init.name); + + /* register the clock */ + clk = devm_clk_register(&pcf85063->rtc->dev, &pcf85063->clkout_hw); + + if (!IS_ERR(clk)) + of_clk_add_provider(pcf85063->rtc->dev.of_node, + of_clk_src_simple_get, clk); + + return clk; +} +#endif + static const struct pcf85063_config pcf85063a_config = { .regmap = { .reg_bits = 8, @@ -457,6 +609,11 @@ static int pcf85063_probe(struct i2c_client *client) nvmem_cfg.priv = pcf85063->regmap; rtc_nvmem_register(pcf85063->rtc, &nvmem_cfg); +#ifdef CONFIG_COMMON_CLK + /* register clk in common clk framework */ + pcf85063_clkout_register_clk(pcf85063); +#endif + return rtc_register_device(pcf85063->rtc); } -- cgit v1.2.3 From 9c328c9dd84a10d4c96a5bfaa0bee43c94b11def Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Fri, 27 Mar 2020 16:44:57 +0800 Subject: rtc: fsl-ftm-alarm: report alarm to core Report interrupt state to the RTC core. Signed-off-by: Biwen Li Link: https://lore.kernel.org/r/20200327084457.45161-1-biwen.li@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-fsl-ftm-alarm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c index 0f4142b35f38..756af62b0486 100644 --- a/drivers/rtc/rtc-fsl-ftm-alarm.c +++ b/drivers/rtc/rtc-fsl-ftm-alarm.c @@ -152,6 +152,8 @@ static irqreturn_t ftm_rtc_alarm_interrupt(int irq, void *dev) { struct ftm_rtc *rtc = dev; + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + ftm_irq_acknowledge(rtc); ftm_irq_disable(rtc); ftm_clean_alarm(rtc); -- cgit v1.2.3 From a29de86521d8a80cb0b426638d4e38707cafa2e2 Mon Sep 17 00:00:00 2001 From: Leonard Crestez Date: Thu, 20 Feb 2020 18:29:38 +0200 Subject: rtc: imx-sc: Align imx sc msg structs to 4 The imx SC api strongly assumes that messages are composed out of 4-bytes words but some of our message structs have odd sizeofs. This produces many oopses with CONFIG_KASAN=y. Fix by marking with __aligned(4). Fixes: a3094fc1a15e ("rtc: imx-sc: add rtc alarm support") Signed-off-by: Leonard Crestez Link: https://lore.kernel.org/r/13404bac8360852d86c61fad5ae5f0c91ffc4cb6.1582216144.git.leonard.crestez@nxp.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-imx-sc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-imx-sc.c b/drivers/rtc/rtc-imx-sc.c index cf2c12107f2b..a5f59e6f862e 100644 --- a/drivers/rtc/rtc-imx-sc.c +++ b/drivers/rtc/rtc-imx-sc.c @@ -37,7 +37,7 @@ struct imx_sc_msg_timer_rtc_set_alarm { u8 hour; u8 min; u8 sec; -} __packed; +} __packed __aligned(4); static int imx_sc_rtc_read_time(struct device *dev, struct rtc_time *tm) { -- cgit v1.2.3 From d17077e570b21276dd6f49c89b03348c6be8f54f Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 30 Mar 2020 00:42:40 +0200 Subject: rtc: da9052: convert to devm_rtc_allocate_device This allows further improvement of the driver. Acked-by: Adam Thomson Link: https://lore.kernel.org/r/20200329224240.776568-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-da9052.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 204eb7cf1aa4..e76561b8ad4c 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -298,12 +298,16 @@ static int da9052_rtc_probe(struct platform_device *pdev) rtc_err(rtc, "Failed to disable TICKS: %d\n", ret); device_init_wakeup(&pdev->dev, true); - rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, - &da9052_rtc_ops, THIS_MODULE); - + rtc->rtc = devm_rtc_allocate_device(&pdev->dev); if (IS_ERR(rtc->rtc)) return PTR_ERR(rtc->rtc); + rtc->rtc->ops = &da9052_rtc_ops; + + ret = rtc_register_device(rtc->rtc); + if (ret) + return ret; + ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM", da9052_rtc_irq, rtc); if (ret != 0) { -- cgit v1.2.3 From 23af616ca4da8af1ee92362d20abbb5e87b9ed88 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:35:46 +0100 Subject: rtc: da9052: set range The da9052 is an rtc valid from 2000 to 2063 (max year is 63). Acked-by: Adam Thomson Link: https://lore.kernel.org/r/20200306073548.57579-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-da9052.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index e76561b8ad4c..39b909d24cc6 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -303,6 +303,8 @@ static int da9052_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->rtc); rtc->rtc->ops = &da9052_rtc_ops; + rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->rtc->range_max = RTC_TIMESTAMP_END_2063; ret = rtc_register_device(rtc->rtc); if (ret) -- cgit v1.2.3 From 06c4e103bf8a292d19697e670fb05a36a197e9da Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 6 Mar 2020 08:35:47 +0100 Subject: rtc: da9052: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Acked-by: Adam Thomson Link: https://lore.kernel.org/r/20200306073548.57579-3-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-da9052.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-da9052.c b/drivers/rtc/rtc-da9052.c index 39b909d24cc6..58de10da37b1 100644 --- a/drivers/rtc/rtc-da9052.c +++ b/drivers/rtc/rtc-da9052.c @@ -103,13 +103,11 @@ static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) int ret; uint8_t v[3]; - ret = rtc_tm_to_time(rtc_tm, &alm_time); - if (ret != 0) - return ret; + alm_time = rtc_tm_to_time64(rtc_tm); if (rtc_tm->tm_sec > 0) { alm_time += 60 - rtc_tm->tm_sec; - rtc_time_to_tm(alm_time, rtc_tm); + rtc_time64_to_tm(alm_time, rtc_tm); } BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */ -- cgit v1.2.3 From fd90d48db0377d4a5a6786ce19d33185c2cbe029 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Mon, 30 Mar 2020 15:55:00 +1300 Subject: rtc: ds1307: add support for watchdog timer on ds1388 The DS1388 variant has watchdog timer capabilities. When using a DS1388 and having enabled CONFIG_WATCHDOG_CORE register a watchdog device for the DS1388. Signed-off-by: Chris Packham Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20200330025500.6991-1-chris.packham@alliedtelesis.co.nz Signed-off-by: Alexandre Belloni --- drivers/rtc/Kconfig | 1 + drivers/rtc/rtc-ds1307.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 417fc6ec9338..f942a3302cdc 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -238,6 +238,7 @@ config RTC_DRV_AS3722 config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057" select REGMAP_I2C + select WATCHDOG_CORE if WATCHDOG help If you say yes here you get support for various compatible RTC chips (often with battery backup) connected with I2C. This driver diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 31a38d468378..fad042118862 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * We can't determine type by probing, but if we expect pre-Linux code @@ -144,8 +145,15 @@ enum ds_type { # define M41TXX_BIT_CALIB_SIGN BIT(5) # define M41TXX_M_CALIBRATION GENMASK(4, 0) +#define DS1388_REG_WDOG_HUN_SECS 0x08 +#define DS1388_REG_WDOG_SECS 0x09 #define DS1388_REG_FLAG 0x0b +# define DS1388_BIT_WF BIT(6) # define DS1388_BIT_OSF BIT(7) +#define DS1388_REG_CONTROL 0x0c +# define DS1388_BIT_RST BIT(0) +# define DS1388_BIT_WDE BIT(1) + /* negative offset step is -2.034ppm */ #define M41TXX_NEG_OFFSET_STEP_PPB 2034 /* positive offset step is +4.068ppm */ @@ -854,6 +862,72 @@ static int m41txx_rtc_set_offset(struct device *dev, long offset) ctrl_reg); } +#ifdef CONFIG_WATCHDOG_CORE +static int ds1388_wdt_start(struct watchdog_device *wdt_dev) +{ + struct ds1307 *ds1307 = watchdog_get_drvdata(wdt_dev); + u8 regs[2]; + int ret; + + ret = regmap_update_bits(ds1307->regmap, DS1388_REG_FLAG, + DS1388_BIT_WF, 0); + if (ret) + return ret; + + ret = regmap_update_bits(ds1307->regmap, DS1388_REG_CONTROL, + DS1388_BIT_WDE | DS1388_BIT_RST, 0); + if (ret) + return ret; + + /* + * watchdog timeouts are measured in seconds. So ignore hundredths of + * seconds field. + */ + regs[0] = 0; + regs[1] = bin2bcd(wdt_dev->timeout); + + ret = regmap_bulk_write(ds1307->regmap, DS1388_REG_WDOG_HUN_SECS, regs, + sizeof(regs)); + if (ret) + return ret; + + return regmap_update_bits(ds1307->regmap, DS1388_REG_CONTROL, + DS1388_BIT_WDE | DS1388_BIT_RST, + DS1388_BIT_WDE | DS1388_BIT_RST); +} + +static int ds1388_wdt_stop(struct watchdog_device *wdt_dev) +{ + struct ds1307 *ds1307 = watchdog_get_drvdata(wdt_dev); + + return regmap_update_bits(ds1307->regmap, DS1388_REG_CONTROL, + DS1388_BIT_WDE | DS1388_BIT_RST, 0); +} + +static int ds1388_wdt_ping(struct watchdog_device *wdt_dev) +{ + struct ds1307 *ds1307 = watchdog_get_drvdata(wdt_dev); + u8 regs[2]; + + return regmap_bulk_read(ds1307->regmap, DS1388_REG_WDOG_HUN_SECS, regs, + sizeof(regs)); +} + +static int ds1388_wdt_set_timeout(struct watchdog_device *wdt_dev, + unsigned int val) +{ + struct ds1307 *ds1307 = watchdog_get_drvdata(wdt_dev); + u8 regs[2]; + + wdt_dev->timeout = val; + regs[0] = 0; + regs[1] = bin2bcd(wdt_dev->timeout); + + return regmap_bulk_write(ds1307->regmap, DS1388_REG_WDOG_HUN_SECS, regs, + sizeof(regs)); +} +#endif + static const struct rtc_class_ops rx8130_rtc_ops = { .read_time = ds1307_get_time, .set_time = ds1307_set_time, @@ -1576,6 +1650,46 @@ static void ds1307_clks_register(struct ds1307 *ds1307) #endif /* CONFIG_COMMON_CLK */ +#ifdef CONFIG_WATCHDOG_CORE +static const struct watchdog_info ds1388_wdt_info = { + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, + .identity = "DS1388 watchdog", +}; + +static const struct watchdog_ops ds1388_wdt_ops = { + .owner = THIS_MODULE, + .start = ds1388_wdt_start, + .stop = ds1388_wdt_stop, + .ping = ds1388_wdt_ping, + .set_timeout = ds1388_wdt_set_timeout, + +}; + +static void ds1307_wdt_register(struct ds1307 *ds1307) +{ + struct watchdog_device *wdt; + + if (ds1307->type != ds_1388) + return; + + wdt = devm_kzalloc(ds1307->dev, sizeof(*wdt), GFP_KERNEL); + + wdt->info = &ds1388_wdt_info; + wdt->ops = &ds1388_wdt_ops; + wdt->timeout = 99; + wdt->max_timeout = 99; + wdt->min_timeout = 1; + + watchdog_init_timeout(wdt, 0, ds1307->dev); + watchdog_set_drvdata(wdt, ds1307); + devm_watchdog_register_device(ds1307->dev, wdt); +} +#else +static void ds1307_wdt_register(struct ds1307 *ds1307) +{ +} +#endif /* CONFIG_WATCHDOG_CORE */ + static const struct regmap_config regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -1865,6 +1979,7 @@ static int ds1307_probe(struct i2c_client *client, ds1307_hwmon_register(ds1307); ds1307_clks_register(ds1307); + ds1307_wdt_register(ds1307); return 0; -- cgit v1.2.3 From 99b7ac9c68fa827264ed8b3f24eace96ab0c67b7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 30 Mar 2020 22:12:26 +0200 Subject: rtc: sun6i: switch to rtc_time64_to_tm/rtc_tm_to_time64 Call the 64bit versions of rtc_tm time conversion. Tested-by: Paul Kocialkowski Link: https://lore.kernel.org/r/20200330201226.860967-2-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 415a20a936e4..7fee729d59db 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -499,7 +499,7 @@ static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN); wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN); - rtc_time_to_tm(chip->alarm, &wkalrm->time); + rtc_time64_to_tm(chip->alarm, &wkalrm->time); return 0; } @@ -520,8 +520,8 @@ static int sun6i_rtc_setalarm(struct device *dev, struct rtc_wkalrm *wkalrm) return -EINVAL; } - rtc_tm_to_time(alrm_tm, &time_set); - rtc_tm_to_time(&tm_now, &time_now); + time_set = rtc_tm_to_time64(alrm_tm); + time_now = rtc_tm_to_time64(&tm_now); if (time_set <= time_now) { dev_err(dev, "Date to set in the past\n"); return -EINVAL; -- cgit v1.2.3 From 8ae79be79b1d31789c2681cf833fae194b0a3851 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 30 Mar 2020 22:12:25 +0200 Subject: rtc: sun6i: let the core handle rtc range Let the rtc core check the date/time against the RTC range. Tested-by: Paul Kocialkowski Link: https://lore.kernel.org/r/20200330201226.860967-1-alexandre.belloni@bootlin.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-sun6i.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 7fee729d59db..e2b8b150bcb4 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -108,7 +108,6 @@ * driver, even though it is somewhat limited. */ #define SUN6I_YEAR_MIN 1970 -#define SUN6I_YEAR_MAX 2033 #define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900) /* @@ -569,14 +568,6 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); u32 date = 0; u32 time = 0; - int year; - - year = rtc_tm->tm_year + 1900; - if (year < SUN6I_YEAR_MIN || year > SUN6I_YEAR_MAX) { - dev_err(dev, "rtc only supports year in range %d - %d\n", - SUN6I_YEAR_MIN, SUN6I_YEAR_MAX); - return -EINVAL; - } rtc_tm->tm_year -= SUN6I_YEAR_OFF; rtc_tm->tm_mon += 1; @@ -585,7 +576,7 @@ static int sun6i_rtc_settime(struct device *dev, struct rtc_time *rtc_tm) SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); - if (is_leap_year(year)) + if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) date |= SUN6I_LEAP_SET_VALUE(1); time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | @@ -726,12 +717,16 @@ static int sun6i_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); - chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i", - &sun6i_rtc_ops, THIS_MODULE); - if (IS_ERR(chip->rtc)) { - dev_err(&pdev->dev, "unable to register device\n"); + chip->rtc = devm_rtc_allocate_device(&pdev->dev); + if (IS_ERR(chip->rtc)) return PTR_ERR(chip->rtc); - } + + chip->rtc->ops = &sun6i_rtc_ops; + chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */ + + ret = rtc_register_device(chip->rtc); + if (ret) + return ret; dev_info(&pdev->dev, "RTC enabled\n"); -- cgit v1.2.3 From 3edf29d9d585237c53f06e44227c4b36c8794222 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 2 Apr 2020 12:04:11 +0100 Subject: rtc: class: remove redundant assignment to variable err The variable err is being initialized with a value that is never read and it is being updated later with a new value. The initialization is redundant and can be removed. Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20200402110411.508534-1-colin.king@canonical.com Signed-off-by: Alexandre Belloni --- drivers/rtc/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 03d6516941a8..7c88d190c51f 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -48,7 +48,7 @@ int rtc_hctosys_ret = -ENODEV; static void rtc_hctosys(struct rtc_device *rtc) { - int err = -ENODEV; + int err; struct rtc_time tm; struct timespec64 tv64 = { .tv_nsec = NSEC_PER_SEC >> 1, -- cgit v1.2.3 From 1821b79d6a7d6973d1630e71380da8bb5e95f3a5 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Fri, 3 Apr 2020 12:04:37 +0100 Subject: rtc: ds1307: check for failed memory allocation on wdt Currently a failed memory allocation will lead to a null pointer dereference on point wdt. Fix this by checking for a failed allocation and just returning. Addresses-Coverity: ("Dereference null return") Fixes: fd90d48db037 ("rtc: ds1307: add support for watchdog timer on ds1388") Signed-off-by: Colin Ian King Link: https://lore.kernel.org/r/20200403110437.57420-1-colin.king@canonical.com Signed-off-by: Alexandre Belloni --- drivers/rtc/rtc-ds1307.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index fad042118862..49702942bb08 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -1673,6 +1673,8 @@ static void ds1307_wdt_register(struct ds1307 *ds1307) return; wdt = devm_kzalloc(ds1307->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return; wdt->info = &ds1388_wdt_info; wdt->ops = &ds1388_wdt_ops; -- cgit v1.2.3