.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) ST-Ericsson SA 2010 |
---|
3 | 4 | * |
---|
4 | | - * License terms: GNU General Public License (GPL) version 2 |
---|
5 | 5 | * Author: Virupax Sadashivpetimath <virupax.sadashivpetimath@stericsson.com> |
---|
6 | 6 | * |
---|
7 | 7 | * RTC clock driver for the RTC part of the AB8500 Power management chip. |
---|
.. | .. |
---|
46 | 46 | #define RTC_STATUS_DATA 0x01 |
---|
47 | 47 | |
---|
48 | 48 | #define COUNTS_PER_SEC (0xF000 / 60) |
---|
49 | | -#define AB8500_RTC_EPOCH 2000 |
---|
50 | 49 | |
---|
51 | 50 | static const u8 ab8500_rtc_time_regs[] = { |
---|
52 | 51 | AB8500_RTC_WATCH_TMIN_HI_REG, AB8500_RTC_WATCH_TMIN_MID_REG, |
---|
.. | .. |
---|
58 | 57 | AB8500_RTC_ALRM_MIN_HI_REG, AB8500_RTC_ALRM_MIN_MID_REG, |
---|
59 | 58 | AB8500_RTC_ALRM_MIN_LOW_REG |
---|
60 | 59 | }; |
---|
61 | | - |
---|
62 | | -/* Calculate the seconds from 1970 to 01-01-2000 00:00:00 */ |
---|
63 | | -static unsigned long get_elapsed_seconds(int year) |
---|
64 | | -{ |
---|
65 | | - unsigned long secs; |
---|
66 | | - struct rtc_time tm = { |
---|
67 | | - .tm_year = year - 1900, |
---|
68 | | - .tm_mday = 1, |
---|
69 | | - }; |
---|
70 | | - |
---|
71 | | - /* |
---|
72 | | - * This function calculates secs from 1970 and not from |
---|
73 | | - * 1900, even if we supply the offset from year 1900. |
---|
74 | | - */ |
---|
75 | | - rtc_tm_to_time(&tm, &secs); |
---|
76 | | - return secs; |
---|
77 | | -} |
---|
78 | 60 | |
---|
79 | 61 | static int ab8500_rtc_read_time(struct device *dev, struct rtc_time *tm) |
---|
80 | 62 | { |
---|
.. | .. |
---|
118 | 100 | secs = secs / COUNTS_PER_SEC; |
---|
119 | 101 | secs = secs + (mins * 60); |
---|
120 | 102 | |
---|
121 | | - /* Add back the initially subtracted number of seconds */ |
---|
122 | | - secs += get_elapsed_seconds(AB8500_RTC_EPOCH); |
---|
123 | | - |
---|
124 | | - rtc_time_to_tm(secs, tm); |
---|
| 103 | + rtc_time64_to_tm(secs, tm); |
---|
125 | 104 | return 0; |
---|
126 | 105 | } |
---|
127 | 106 | |
---|
.. | .. |
---|
131 | 110 | unsigned char buf[ARRAY_SIZE(ab8500_rtc_time_regs)]; |
---|
132 | 111 | unsigned long no_secs, no_mins, secs = 0; |
---|
133 | 112 | |
---|
134 | | - if (tm->tm_year < (AB8500_RTC_EPOCH - 1900)) { |
---|
135 | | - dev_dbg(dev, "year should be equal to or greater than %d\n", |
---|
136 | | - AB8500_RTC_EPOCH); |
---|
137 | | - return -EINVAL; |
---|
138 | | - } |
---|
139 | | - |
---|
140 | | - /* Get the number of seconds since 1970 */ |
---|
141 | | - rtc_tm_to_time(tm, &secs); |
---|
142 | | - |
---|
143 | | - /* |
---|
144 | | - * Convert it to the number of seconds since 01-01-2000 00:00:00, since |
---|
145 | | - * we only have a small counter in the RTC. |
---|
146 | | - */ |
---|
147 | | - secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); |
---|
| 113 | + secs = rtc_tm_to_time64(tm); |
---|
148 | 114 | |
---|
149 | 115 | no_mins = secs / 60; |
---|
150 | 116 | |
---|
.. | .. |
---|
202 | 168 | mins = (buf[0] << 16) | (buf[1] << 8) | (buf[2]); |
---|
203 | 169 | secs = mins * 60; |
---|
204 | 170 | |
---|
205 | | - /* Add back the initially subtracted number of seconds */ |
---|
206 | | - secs += get_elapsed_seconds(AB8500_RTC_EPOCH); |
---|
| 171 | + rtc_time64_to_tm(secs, &alarm->time); |
---|
207 | 172 | |
---|
208 | | - rtc_time_to_tm(secs, &alarm->time); |
---|
209 | | - |
---|
210 | | - return rtc_valid_tm(&alarm->time); |
---|
| 173 | + return 0; |
---|
211 | 174 | } |
---|
212 | 175 | |
---|
213 | 176 | static int ab8500_rtc_irq_enable(struct device *dev, unsigned int enabled) |
---|
.. | .. |
---|
224 | 187 | unsigned long mins, secs = 0, cursec = 0; |
---|
225 | 188 | struct rtc_time curtm; |
---|
226 | 189 | |
---|
227 | | - if (alarm->time.tm_year < (AB8500_RTC_EPOCH - 1900)) { |
---|
228 | | - dev_dbg(dev, "year should be equal to or greater than %d\n", |
---|
229 | | - AB8500_RTC_EPOCH); |
---|
230 | | - return -EINVAL; |
---|
231 | | - } |
---|
232 | | - |
---|
233 | 190 | /* Get the number of seconds since 1970 */ |
---|
234 | | - rtc_tm_to_time(&alarm->time, &secs); |
---|
| 191 | + secs = rtc_tm_to_time64(&alarm->time); |
---|
235 | 192 | |
---|
236 | 193 | /* |
---|
237 | 194 | * Check whether alarm is set less than 1min. |
---|
.. | .. |
---|
239 | 196 | * return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON |
---|
240 | 197 | */ |
---|
241 | 198 | ab8500_rtc_read_time(dev, &curtm); /* Read current time */ |
---|
242 | | - rtc_tm_to_time(&curtm, &cursec); |
---|
| 199 | + cursec = rtc_tm_to_time64(&curtm); |
---|
243 | 200 | if ((secs - cursec) < 59) { |
---|
244 | 201 | dev_dbg(dev, "Alarm less than 1 minute not supported\r\n"); |
---|
245 | 202 | return -EINVAL; |
---|
246 | 203 | } |
---|
247 | | - |
---|
248 | | - /* |
---|
249 | | - * Convert it to the number of seconds since 01-01-2000 00:00:00, since |
---|
250 | | - * we only have a small counter in the RTC. |
---|
251 | | - */ |
---|
252 | | - secs -= get_elapsed_seconds(AB8500_RTC_EPOCH); |
---|
253 | 204 | |
---|
254 | 205 | mins = secs / 60; |
---|
255 | 206 | |
---|
.. | .. |
---|
360 | 311 | ab8500_sysfs_show_rtc_calibration, |
---|
361 | 312 | ab8500_sysfs_store_rtc_calibration); |
---|
362 | 313 | |
---|
363 | | -static int ab8500_sysfs_rtc_register(struct device *dev) |
---|
364 | | -{ |
---|
365 | | - return device_create_file(dev, &dev_attr_rtc_calibration); |
---|
366 | | -} |
---|
| 314 | +static struct attribute *ab8500_rtc_attrs[] = { |
---|
| 315 | + &dev_attr_rtc_calibration.attr, |
---|
| 316 | + NULL |
---|
| 317 | +}; |
---|
367 | 318 | |
---|
368 | | -static void ab8500_sysfs_rtc_unregister(struct device *dev) |
---|
369 | | -{ |
---|
370 | | - device_remove_file(dev, &dev_attr_rtc_calibration); |
---|
371 | | -} |
---|
| 319 | +static const struct attribute_group ab8500_rtc_sysfs_files = { |
---|
| 320 | + .attrs = ab8500_rtc_attrs, |
---|
| 321 | +}; |
---|
372 | 322 | |
---|
373 | 323 | static irqreturn_t rtc_alarm_handler(int irq, void *data) |
---|
374 | 324 | { |
---|
.. | .. |
---|
429 | 379 | |
---|
430 | 380 | device_init_wakeup(&pdev->dev, true); |
---|
431 | 381 | |
---|
432 | | - rtc = devm_rtc_device_register(&pdev->dev, "ab8500-rtc", |
---|
433 | | - (struct rtc_class_ops *)platid->driver_data, |
---|
434 | | - THIS_MODULE); |
---|
435 | | - if (IS_ERR(rtc)) { |
---|
436 | | - dev_err(&pdev->dev, "Registration failed\n"); |
---|
437 | | - err = PTR_ERR(rtc); |
---|
438 | | - return err; |
---|
439 | | - } |
---|
| 382 | + rtc = devm_rtc_allocate_device(&pdev->dev); |
---|
| 383 | + if (IS_ERR(rtc)) |
---|
| 384 | + return PTR_ERR(rtc); |
---|
| 385 | + |
---|
| 386 | + rtc->ops = (struct rtc_class_ops *)platid->driver_data; |
---|
440 | 387 | |
---|
441 | 388 | err = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
---|
442 | 389 | rtc_alarm_handler, IRQF_ONESHOT, |
---|
.. | .. |
---|
447 | 394 | dev_pm_set_wake_irq(&pdev->dev, irq); |
---|
448 | 395 | platform_set_drvdata(pdev, rtc); |
---|
449 | 396 | |
---|
450 | | - err = ab8500_sysfs_rtc_register(&pdev->dev); |
---|
451 | | - if (err) { |
---|
452 | | - dev_err(&pdev->dev, "sysfs RTC failed to register\n"); |
---|
453 | | - return err; |
---|
454 | | - } |
---|
455 | | - |
---|
456 | 397 | rtc->uie_unsupported = 1; |
---|
457 | 398 | |
---|
458 | | - return 0; |
---|
| 399 | + rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs |
---|
| 400 | + rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000; |
---|
| 401 | + rtc->set_start_time = true; |
---|
| 402 | + |
---|
| 403 | + err = rtc_add_group(rtc, &ab8500_rtc_sysfs_files); |
---|
| 404 | + if (err) |
---|
| 405 | + return err; |
---|
| 406 | + |
---|
| 407 | + return rtc_register_device(rtc); |
---|
459 | 408 | } |
---|
460 | 409 | |
---|
461 | 410 | static int ab8500_rtc_remove(struct platform_device *pdev) |
---|
462 | 411 | { |
---|
463 | 412 | dev_pm_clear_wake_irq(&pdev->dev); |
---|
464 | 413 | device_init_wakeup(&pdev->dev, false); |
---|
465 | | - ab8500_sysfs_rtc_unregister(&pdev->dev); |
---|
466 | 414 | |
---|
467 | 415 | return 0; |
---|
468 | 416 | } |
---|