diff options
Diffstat (limited to 'drivers/rtc/rtc-goldfish.c')
-rw-r--r-- | drivers/rtc/rtc-goldfish.c | 50 |
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 | ||
104 | static int goldfish_rtc_alarm_irq_enable(struct device *dev, | 90 | static 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 | ||
176 | static const struct rtc_class_ops goldfish_rtc_ops = { | 157 | static 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 | ||
223 | static const struct of_device_id goldfish_rtc_of_match[] = { | 205 | static const struct of_device_id goldfish_rtc_of_match[] = { |