aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-imxdi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:46:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-05-09 17:46:33 -0400
commit8e4ff713ce313dcabbb60e6ede1ffc193e67631f (patch)
tree8efdfe4925570ec8608d40e229ed01a5432d901e /drivers/rtc/rtc-imxdi.c
parent45182e4e1f8ac04708ca7508c51d9103f07d81ab (diff)
parentdacb6a4035a010e41abaf81c1cfe2beadfb05ec8 (diff)
Merge tag 'rtc-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni: "A huge series from me this cycle. I went through many drivers to set the date and time range supported by the RTC which helps solving HW limitation when the time comes (as early as next year for some). This time, I focused on drivers using .set_mms and .set_mmss64, allowing me to remove those callbacks. About a third of the patches got reviews, I actually own the RTCs and I tested another third and the remaining one are unlikely to cause any issues. Other than that, a single new driver and the usual fixes here and there. Summary: Subsystem: - set_mmss and set_mmss64 rtc_ops removal - Fix timestamp value for RTC_TIMESTAMP_BEGIN_1900 - Use SPDX identifier for the core - validate upper bound of tm->tm_year New driver: - Aspeed BMC SoC RTC Drivers: - abx80x: use rtc_add_group - ds3232: nvram support - pcf85063: add alarm, nvram, offset correction and microcrystal rv8263 support - x1205: add of_match_table - Use set_time instead of set_mms/set_mmss64 for: ab3100, coh901331, digicolor, ds1672, ds2404, ep93xx, imxdi, jz4740, lpc32xx, mc13xxx, mxc, pcap, stmp3xxx, test, wm831x, xgene. - Set RTC range for: ab3100, at91sam9, coh901331, da9063, digicolor, dm355evm, ds1672, ds2404, ep39xx, goldfish, imxdi, jz4740, lpc32xx, mc13xxx, mv, mxc, omap, pcap, pcf85063, pcf85363, ps3, sh, stmp3xxx, sun4v, tegra, wm831x, xgene. - Switch to rtc_time64_to_tm/rtc_tm_to_time64 for the driver that properly set the RTC range. - Use dev_get_drvdata instead of multiple indirections" * tag 'rtc-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (177 commits) rtc: snvs: Use __maybe_unused instead of #if CONFIG_PM_SLEEP rtc: imxdi: remove unused variable rtc: drop set_mms and set_mmss64 rtc: pcap: convert to SPDX identifier rtc: pcap: use .set_time rtc: pcap: switch to rtc_time64_to_tm/rtc_tm_to_time64 rtc: pcap: set range rtc: digicolor: convert to SPDX identifier rtc: digicolor: use .set_time rtc: digicolor: set range rtc: digicolor: fix possible race condition rtc: jz4740: convert to SPDX identifier rtc: jz4740: rework invalid time detection rtc: jz4740: use dev_pm_set_wake_irq() to simplify code rtc: jz4740: use .set_time rtc: jz4740: remove useless check rtc: jz4740: switch to rtc_time64_to_tm/rtc_tm_to_time64 rtc: jz4740: set range rtc: 88pm860x: prevent use-after-free on device remove rtc: Use dev_get_drvdata() ...
Diffstat (limited to 'drivers/rtc/rtc-imxdi.c')
-rw-r--r--drivers/rtc/rtc-imxdi.c50
1 files changed, 17 insertions, 33 deletions
diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c
index 80931114c899..3f3d652a0b0f 100644
--- a/drivers/rtc/rtc-imxdi.c
+++ b/drivers/rtc/rtc-imxdi.c
@@ -1,20 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0+
1/* 2/*
2 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. 3 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
3 * Copyright 2010 Orex Computed Radiography 4 * Copyright 2010 Orex Computed Radiography
4 */ 5 */
5 6
6/* 7/*
7 * The code contained herein is licensed under the GNU General Public
8 * License. You may obtain a copy of the GNU General Public License
9 * Version 2 or later at the following locations:
10 *
11 * http://www.opensource.org/licenses/gpl-license.html
12 * http://www.gnu.org/copyleft/gpl.html
13 */
14
15/* based on rtc-mc13892.c */
16
17/*
18 * This driver uses the 47-bit 32 kHz counter in the Freescale DryIce block 8 * This driver uses the 47-bit 32 kHz counter in the Freescale DryIce block
19 * to implement a Linux RTC. Times and alarms are truncated to seconds. 9 * to implement a Linux RTC. Times and alarms are truncated to seconds.
20 * Since the RTC framework performs API locking via rtc->ops_lock the 10 * Since the RTC framework performs API locking via rtc->ops_lock the
@@ -552,7 +542,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
552 unsigned long now; 542 unsigned long now;
553 543
554 now = readl(imxdi->ioaddr + DTCMR); 544 now = readl(imxdi->ioaddr + DTCMR);
555 rtc_time_to_tm(now, tm); 545 rtc_time64_to_tm(now, tm);
556 546
557 return 0; 547 return 0;
558} 548}
@@ -561,7 +551,7 @@ static int dryice_rtc_read_time(struct device *dev, struct rtc_time *tm)
561 * set the seconds portion of dryice time counter and clear the 551 * set the seconds portion of dryice time counter and clear the
562 * fractional part. 552 * fractional part.
563 */ 553 */
564static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs) 554static int dryice_rtc_set_time(struct device *dev, struct rtc_time *tm)
565{ 555{
566 struct imxdi_dev *imxdi = dev_get_drvdata(dev); 556 struct imxdi_dev *imxdi = dev_get_drvdata(dev);
567 u32 dcr, dsr; 557 u32 dcr, dsr;
@@ -588,7 +578,7 @@ static int dryice_rtc_set_mmss(struct device *dev, unsigned long secs)
588 if (rc != 0) 578 if (rc != 0)
589 return rc; 579 return rc;
590 580
591 rc = di_write_wait(imxdi, secs, DTCMR); 581 rc = di_write_wait(imxdi, rtc_tm_to_time64(tm), DTCMR);
592 if (rc != 0) 582 if (rc != 0)
593 return rc; 583 return rc;
594 584
@@ -618,7 +608,7 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
618 u32 dcamr; 608 u32 dcamr;
619 609
620 dcamr = readl(imxdi->ioaddr + DCAMR); 610 dcamr = readl(imxdi->ioaddr + DCAMR);
621 rtc_time_to_tm(dcamr, &alarm->time); 611 rtc_time64_to_tm(dcamr, &alarm->time);
622 612
623 /* alarm is enabled if the interrupt is enabled */ 613 /* alarm is enabled if the interrupt is enabled */
624 alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0; 614 alarm->enabled = (readl(imxdi->ioaddr + DIER) & DIER_CAIE) != 0;
@@ -640,21 +630,10 @@ static int dryice_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
640static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 630static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
641{ 631{
642 struct imxdi_dev *imxdi = dev_get_drvdata(dev); 632 struct imxdi_dev *imxdi = dev_get_drvdata(dev);
643 unsigned long now;
644 unsigned long alarm_time;
645 int rc; 633 int rc;
646 634
647 rc = rtc_tm_to_time(&alarm->time, &alarm_time);
648 if (rc)
649 return rc;
650
651 /* don't allow setting alarm in the past */
652 now = readl(imxdi->ioaddr + DTCMR);
653 if (alarm_time < now)
654 return -EINVAL;
655
656 /* write the new alarm time */ 635 /* write the new alarm time */
657 rc = di_write_wait(imxdi, (u32)alarm_time, DCAMR); 636 rc = di_write_wait(imxdi, rtc_tm_to_time64(&alarm->time), DCAMR);
658 if (rc) 637 if (rc)
659 return rc; 638 return rc;
660 639
@@ -668,7 +647,7 @@ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
668 647
669static const struct rtc_class_ops dryice_rtc_ops = { 648static const struct rtc_class_ops dryice_rtc_ops = {
670 .read_time = dryice_rtc_read_time, 649 .read_time = dryice_rtc_read_time,
671 .set_mmss = dryice_rtc_set_mmss, 650 .set_time = dryice_rtc_set_time,
672 .alarm_irq_enable = dryice_rtc_alarm_irq_enable, 651 .alarm_irq_enable = dryice_rtc_alarm_irq_enable,
673 .read_alarm = dryice_rtc_read_alarm, 652 .read_alarm = dryice_rtc_read_alarm,
674 .set_alarm = dryice_rtc_set_alarm, 653 .set_alarm = dryice_rtc_set_alarm,
@@ -796,6 +775,10 @@ static int __init dryice_rtc_probe(struct platform_device *pdev)
796 775
797 mutex_init(&imxdi->write_mutex); 776 mutex_init(&imxdi->write_mutex);
798 777
778 imxdi->rtc = devm_rtc_allocate_device(&pdev->dev);
779 if (IS_ERR(imxdi->rtc))
780 return PTR_ERR(imxdi->rtc);
781
799 imxdi->clk = devm_clk_get(&pdev->dev, NULL); 782 imxdi->clk = devm_clk_get(&pdev->dev, NULL);
800 if (IS_ERR(imxdi->clk)) 783 if (IS_ERR(imxdi->clk))
801 return PTR_ERR(imxdi->clk); 784 return PTR_ERR(imxdi->clk);
@@ -829,12 +812,13 @@ static int __init dryice_rtc_probe(struct platform_device *pdev)
829 } 812 }
830 813
831 platform_set_drvdata(pdev, imxdi); 814 platform_set_drvdata(pdev, imxdi);
832 imxdi->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 815
833 &dryice_rtc_ops, THIS_MODULE); 816 imxdi->rtc->ops = &dryice_rtc_ops;
834 if (IS_ERR(imxdi->rtc)) { 817 imxdi->rtc->range_max = U32_MAX;
835 rc = PTR_ERR(imxdi->rtc); 818
819 rc = rtc_register_device(imxdi->rtc);
820 if (rc)
836 goto err; 821 goto err;
837 }
838 822
839 return 0; 823 return 0;
840 824