aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-goldfish.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-goldfish.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-goldfish.c')
-rw-r--r--drivers/rtc/rtc-goldfish.c50
1 files changed, 16 insertions, 34 deletions
diff --git a/drivers/rtc/rtc-goldfish.c b/drivers/rtc/rtc-goldfish.c
index a1c44d0c8557..1a3420ee6a4d 100644
--- a/drivers/rtc/rtc-goldfish.c
+++ b/drivers/rtc/rtc-goldfish.c
@@ -1,23 +1,15 @@
1// SPDX-License-Identifier: GPL-2.0
1/* drivers/rtc/rtc-goldfish.c 2/* drivers/rtc/rtc-goldfish.c
2 * 3 *
3 * Copyright (C) 2007 Google, Inc. 4 * Copyright (C) 2007 Google, Inc.
4 * Copyright (C) 2017 Imagination Technologies Ltd. 5 * Copyright (C) 2017 Imagination Technologies Ltd.
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */ 6 */
16 7
8#include <linux/io.h>
17#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/of.h>
18#include <linux/platform_device.h> 11#include <linux/platform_device.h>
19#include <linux/rtc.h> 12#include <linux/rtc.h>
20#include <linux/io.h>
21 13
22#define TIMER_TIME_LOW 0x00 /* get low bits of current time */ 14#define TIMER_TIME_LOW 0x00 /* get low bits of current time */
23 /* and update TIMER_TIME_HIGH */ 15 /* and update TIMER_TIME_HIGH */
@@ -56,7 +48,7 @@ static int goldfish_rtc_read_alarm(struct device *dev,
56 do_div(rtc_alarm, NSEC_PER_SEC); 48 do_div(rtc_alarm, NSEC_PER_SEC);
57 memset(alrm, 0, sizeof(struct rtc_wkalrm)); 49 memset(alrm, 0, sizeof(struct rtc_wkalrm));
58 50
59 rtc_time_to_tm(rtc_alarm, &alrm->time); 51 rtc_time64_to_tm(rtc_alarm, &alrm->time);
60 52
61 if (readl(base + TIMER_ALARM_STATUS)) 53 if (readl(base + TIMER_ALARM_STATUS))
62 alrm->enabled = 1; 54 alrm->enabled = 1;
@@ -70,21 +62,15 @@ static int goldfish_rtc_set_alarm(struct device *dev,
70 struct rtc_wkalrm *alrm) 62 struct rtc_wkalrm *alrm)
71{ 63{
72 struct goldfish_rtc *rtcdrv; 64 struct goldfish_rtc *rtcdrv;
73 unsigned long rtc_alarm;
74 u64 rtc_alarm64; 65 u64 rtc_alarm64;
75 u64 rtc_status_reg; 66 u64 rtc_status_reg;
76 void __iomem *base; 67 void __iomem *base;
77 int ret = 0;
78 68
79 rtcdrv = dev_get_drvdata(dev); 69 rtcdrv = dev_get_drvdata(dev);
80 base = rtcdrv->base; 70 base = rtcdrv->base;
81 71
82 if (alrm->enabled) { 72 if (alrm->enabled) {
83 ret = rtc_tm_to_time(&alrm->time, &rtc_alarm); 73 rtc_alarm64 = rtc_tm_to_time64(&alrm->time) * NSEC_PER_SEC;
84 if (ret != 0)
85 return ret;
86
87 rtc_alarm64 = rtc_alarm * NSEC_PER_SEC;
88 writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH); 74 writel((rtc_alarm64 >> 32), base + TIMER_ALARM_HIGH);
89 writel(rtc_alarm64, base + TIMER_ALARM_LOW); 75 writel(rtc_alarm64, base + TIMER_ALARM_LOW);
90 } else { 76 } else {
@@ -98,7 +84,7 @@ static int goldfish_rtc_set_alarm(struct device *dev,
98 writel(1, base + TIMER_CLEAR_ALARM); 84 writel(1, base + TIMER_CLEAR_ALARM);
99 } 85 }
100 86
101 return ret; 87 return 0;
102} 88}
103 89
104static int goldfish_rtc_alarm_irq_enable(struct device *dev, 90static int goldfish_rtc_alarm_irq_enable(struct device *dev,
@@ -147,7 +133,7 @@ static int goldfish_rtc_read_time(struct device *dev, struct rtc_time *tm)
147 133
148 do_div(time, NSEC_PER_SEC); 134 do_div(time, NSEC_PER_SEC);
149 135
150 rtc_time_to_tm(time, tm); 136 rtc_time64_to_tm(time, tm);
151 137
152 return 0; 138 return 0;
153} 139}
@@ -156,21 +142,16 @@ static int goldfish_rtc_set_time(struct device *dev, struct rtc_time *tm)
156{ 142{
157 struct goldfish_rtc *rtcdrv; 143 struct goldfish_rtc *rtcdrv;
158 void __iomem *base; 144 void __iomem *base;
159 unsigned long now;
160 u64 now64; 145 u64 now64;
161 int ret;
162 146
163 rtcdrv = dev_get_drvdata(dev); 147 rtcdrv = dev_get_drvdata(dev);
164 base = rtcdrv->base; 148 base = rtcdrv->base;
165 149
166 ret = rtc_tm_to_time(tm, &now); 150 now64 = rtc_tm_to_time64(tm) * NSEC_PER_SEC;
167 if (ret == 0) { 151 writel((now64 >> 32), base + TIMER_TIME_HIGH);
168 now64 = now * NSEC_PER_SEC; 152 writel(now64, base + TIMER_TIME_LOW);
169 writel((now64 >> 32), base + TIMER_TIME_HIGH);
170 writel(now64, base + TIMER_TIME_LOW);
171 }
172 153
173 return ret; 154 return 0;
174} 155}
175 156
176static const struct rtc_class_ops goldfish_rtc_ops = { 157static const struct rtc_class_ops goldfish_rtc_ops = {
@@ -205,19 +186,20 @@ static int goldfish_rtc_probe(struct platform_device *pdev)
205 if (rtcdrv->irq < 0) 186 if (rtcdrv->irq < 0)
206 return -ENODEV; 187 return -ENODEV;
207 188
208 rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 189 rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev);
209 &goldfish_rtc_ops,
210 THIS_MODULE);
211 if (IS_ERR(rtcdrv->rtc)) 190 if (IS_ERR(rtcdrv->rtc))
212 return PTR_ERR(rtcdrv->rtc); 191 return PTR_ERR(rtcdrv->rtc);
213 192
193 rtcdrv->rtc->ops = &goldfish_rtc_ops;
194 rtcdrv->rtc->range_max = U64_MAX / NSEC_PER_SEC;
195
214 err = devm_request_irq(&pdev->dev, rtcdrv->irq, 196 err = devm_request_irq(&pdev->dev, rtcdrv->irq,
215 goldfish_rtc_interrupt, 197 goldfish_rtc_interrupt,
216 0, pdev->name, rtcdrv); 198 0, pdev->name, rtcdrv);
217 if (err) 199 if (err)
218 return err; 200 return err;
219 201
220 return 0; 202 return rtc_register_device(rtcdrv->rtc);
221} 203}
222 204
223static const struct of_device_id goldfish_rtc_of_match[] = { 205static const struct of_device_id goldfish_rtc_of_match[] = {