.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2007-2009 ST-Ericsson AB |
---|
3 | | - * License terms: GNU General Public License (GPL) version 2 |
---|
4 | 4 | * Real Time Clock interface for ST-Ericsson AB COH 901 331 RTC. |
---|
5 | 5 | * Author: Linus Walleij <linus.walleij@stericsson.com> |
---|
6 | 6 | * Based on rtc-pl031.c by Deepak Saxena <dsaxena@plexity.net> |
---|
.. | .. |
---|
80 | 80 | |
---|
81 | 81 | clk_enable(rtap->clk); |
---|
82 | 82 | /* Check if the time is valid */ |
---|
83 | | - if (readl(rtap->virtbase + COH901331_VALID)) { |
---|
84 | | - rtc_time_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); |
---|
| 83 | + if (!readl(rtap->virtbase + COH901331_VALID)) { |
---|
85 | 84 | clk_disable(rtap->clk); |
---|
86 | | - return 0; |
---|
| 85 | + return -EINVAL; |
---|
87 | 86 | } |
---|
| 87 | + |
---|
| 88 | + rtc_time64_to_tm(readl(rtap->virtbase + COH901331_CUR_TIME), tm); |
---|
88 | 89 | clk_disable(rtap->clk); |
---|
89 | | - return -EINVAL; |
---|
| 90 | + return 0; |
---|
90 | 91 | } |
---|
91 | 92 | |
---|
92 | | -static int coh901331_set_mmss(struct device *dev, unsigned long secs) |
---|
| 93 | +static int coh901331_set_time(struct device *dev, struct rtc_time *tm) |
---|
93 | 94 | { |
---|
94 | 95 | struct coh901331_port *rtap = dev_get_drvdata(dev); |
---|
95 | 96 | |
---|
96 | 97 | clk_enable(rtap->clk); |
---|
97 | | - writel(secs, rtap->virtbase + COH901331_SET_TIME); |
---|
| 98 | + writel(rtc_tm_to_time64(tm), rtap->virtbase + COH901331_SET_TIME); |
---|
98 | 99 | clk_disable(rtap->clk); |
---|
99 | 100 | |
---|
100 | 101 | return 0; |
---|
.. | .. |
---|
105 | 106 | struct coh901331_port *rtap = dev_get_drvdata(dev); |
---|
106 | 107 | |
---|
107 | 108 | clk_enable(rtap->clk); |
---|
108 | | - rtc_time_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); |
---|
| 109 | + rtc_time64_to_tm(readl(rtap->virtbase + COH901331_ALARM), &alarm->time); |
---|
109 | 110 | alarm->pending = readl(rtap->virtbase + COH901331_IRQ_EVENT) & 1U; |
---|
110 | 111 | alarm->enabled = readl(rtap->virtbase + COH901331_IRQ_MASK) & 1U; |
---|
111 | 112 | clk_disable(rtap->clk); |
---|
.. | .. |
---|
116 | 117 | static int coh901331_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) |
---|
117 | 118 | { |
---|
118 | 119 | struct coh901331_port *rtap = dev_get_drvdata(dev); |
---|
119 | | - unsigned long time; |
---|
| 120 | + unsigned long time = rtc_tm_to_time64(&alarm->time); |
---|
120 | 121 | |
---|
121 | | - rtc_tm_to_time(&alarm->time, &time); |
---|
122 | 122 | clk_enable(rtap->clk); |
---|
123 | 123 | writel(time, rtap->virtbase + COH901331_ALARM); |
---|
124 | 124 | writel(alarm->enabled, rtap->virtbase + COH901331_IRQ_MASK); |
---|
.. | .. |
---|
143 | 143 | |
---|
144 | 144 | static const struct rtc_class_ops coh901331_ops = { |
---|
145 | 145 | .read_time = coh901331_read_time, |
---|
146 | | - .set_mmss = coh901331_set_mmss, |
---|
| 146 | + .set_time = coh901331_set_time, |
---|
147 | 147 | .read_alarm = coh901331_read_alarm, |
---|
148 | 148 | .set_alarm = coh901331_set_alarm, |
---|
149 | 149 | .alarm_irq_enable = coh901331_alarm_irq_enable, |
---|
.. | .. |
---|
164 | 164 | { |
---|
165 | 165 | int ret; |
---|
166 | 166 | struct coh901331_port *rtap; |
---|
167 | | - struct resource *res; |
---|
168 | 167 | |
---|
169 | 168 | rtap = devm_kzalloc(&pdev->dev, |
---|
170 | 169 | sizeof(struct coh901331_port), GFP_KERNEL); |
---|
171 | 170 | if (!rtap) |
---|
172 | 171 | return -ENOMEM; |
---|
173 | 172 | |
---|
174 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
175 | | - rtap->virtbase = devm_ioremap_resource(&pdev->dev, res); |
---|
| 173 | + rtap->virtbase = devm_platform_ioremap_resource(pdev, 0); |
---|
176 | 174 | if (IS_ERR(rtap->virtbase)) |
---|
177 | 175 | return PTR_ERR(rtap->virtbase); |
---|
178 | 176 | |
---|
.. | .. |
---|
188 | 186 | return ret; |
---|
189 | 187 | } |
---|
190 | 188 | |
---|
| 189 | + rtap->rtc = devm_rtc_allocate_device(&pdev->dev); |
---|
| 190 | + if (IS_ERR(rtap->rtc)) |
---|
| 191 | + return PTR_ERR(rtap->rtc); |
---|
| 192 | + |
---|
| 193 | + rtap->rtc->ops = &coh901331_ops; |
---|
| 194 | + rtap->rtc->range_max = U32_MAX; |
---|
| 195 | + |
---|
191 | 196 | /* We enable/disable the clock only to assure it works */ |
---|
192 | 197 | ret = clk_prepare_enable(rtap->clk); |
---|
193 | 198 | if (ret) { |
---|
.. | .. |
---|
197 | 202 | clk_disable(rtap->clk); |
---|
198 | 203 | |
---|
199 | 204 | platform_set_drvdata(pdev, rtap); |
---|
200 | | - rtap->rtc = devm_rtc_device_register(&pdev->dev, "coh901331", |
---|
201 | | - &coh901331_ops, THIS_MODULE); |
---|
202 | | - if (IS_ERR(rtap->rtc)) { |
---|
203 | | - ret = PTR_ERR(rtap->rtc); |
---|
| 205 | + |
---|
| 206 | + ret = rtc_register_device(rtap->rtc); |
---|
| 207 | + if (ret) |
---|
204 | 208 | goto out_no_rtc; |
---|
205 | | - } |
---|
206 | 209 | |
---|
207 | 210 | return 0; |
---|
208 | 211 | |
---|
.. | .. |
---|
235 | 238 | |
---|
236 | 239 | static int coh901331_resume(struct device *dev) |
---|
237 | 240 | { |
---|
| 241 | + int ret; |
---|
238 | 242 | struct coh901331_port *rtap = dev_get_drvdata(dev); |
---|
239 | 243 | |
---|
240 | | - clk_prepare(rtap->clk); |
---|
| 244 | + ret = clk_prepare(rtap->clk); |
---|
| 245 | + if (ret) |
---|
| 246 | + return ret; |
---|
| 247 | + |
---|
241 | 248 | if (device_may_wakeup(dev)) { |
---|
242 | 249 | disable_irq_wake(rtap->irq); |
---|
243 | 250 | } else { |
---|