| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * RTC subsystem, interface functions |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Author: Alessandro Zummo <a.zummo@towertech.it> |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * based on arch/arm/common/rtctime.c |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 11 | | - * published by the Free Software Foundation. |
|---|
| 12 | | -*/ |
|---|
| 9 | + */ |
|---|
| 13 | 10 | |
|---|
| 14 | 11 | #include <linux/rtc.h> |
|---|
| 15 | 12 | #include <linux/sched.h> |
|---|
| .. | .. |
|---|
| 73 | 70 | time64_t time = rtc_tm_to_time64(tm); |
|---|
| 74 | 71 | time64_t range_min = rtc->set_start_time ? rtc->start_secs : |
|---|
| 75 | 72 | rtc->range_min; |
|---|
| 76 | | - time64_t range_max = rtc->set_start_time ? |
|---|
| 73 | + timeu64_t range_max = rtc->set_start_time ? |
|---|
| 77 | 74 | (rtc->start_secs + rtc->range_max - rtc->range_min) : |
|---|
| 78 | 75 | rtc->range_max; |
|---|
| 79 | 76 | |
|---|
| .. | .. |
|---|
| 87 | 84 | static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) |
|---|
| 88 | 85 | { |
|---|
| 89 | 86 | int err; |
|---|
| 90 | | - if (!rtc->ops) |
|---|
| 87 | + |
|---|
| 88 | + if (!rtc->ops) { |
|---|
| 91 | 89 | err = -ENODEV; |
|---|
| 92 | | - else if (!rtc->ops->read_time) |
|---|
| 90 | + } else if (!rtc->ops->read_time) { |
|---|
| 93 | 91 | err = -EINVAL; |
|---|
| 94 | | - else { |
|---|
| 92 | + } else { |
|---|
| 95 | 93 | memset(tm, 0, sizeof(struct rtc_time)); |
|---|
| 96 | 94 | err = rtc->ops->read_time(rtc->dev.parent, tm); |
|---|
| 97 | 95 | if (err < 0) { |
|---|
| .. | .. |
|---|
| 158 | 156 | err = -ENODEV; |
|---|
| 159 | 157 | else if (rtc->ops->set_time) |
|---|
| 160 | 158 | err = rtc->ops->set_time(rtc->dev.parent, tm); |
|---|
| 161 | | - else if (rtc->ops->set_mmss64) { |
|---|
| 162 | | - time64_t secs64 = rtc_tm_to_time64(tm); |
|---|
| 163 | | - |
|---|
| 164 | | - err = rtc->ops->set_mmss64(rtc->dev.parent, secs64); |
|---|
| 165 | | - } else if (rtc->ops->set_mmss) { |
|---|
| 166 | | - time64_t secs64 = rtc_tm_to_time64(tm); |
|---|
| 167 | | - err = rtc->ops->set_mmss(rtc->dev.parent, secs64); |
|---|
| 168 | | - } else |
|---|
| 159 | + else |
|---|
| 169 | 160 | err = -EINVAL; |
|---|
| 170 | 161 | |
|---|
| 171 | 162 | pm_stay_awake(rtc->dev.parent); |
|---|
| .. | .. |
|---|
| 184 | 175 | } |
|---|
| 185 | 176 | EXPORT_SYMBOL_GPL(rtc_set_time); |
|---|
| 186 | 177 | |
|---|
| 187 | | -static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
|---|
| 178 | +static int rtc_read_alarm_internal(struct rtc_device *rtc, |
|---|
| 179 | + struct rtc_wkalrm *alarm) |
|---|
| 188 | 180 | { |
|---|
| 189 | 181 | int err; |
|---|
| 190 | 182 | |
|---|
| .. | .. |
|---|
| 192 | 184 | if (err) |
|---|
| 193 | 185 | return err; |
|---|
| 194 | 186 | |
|---|
| 195 | | - if (rtc->ops == NULL) |
|---|
| 187 | + if (!rtc->ops) { |
|---|
| 196 | 188 | err = -ENODEV; |
|---|
| 197 | | - else if (!rtc->ops->read_alarm) |
|---|
| 189 | + } else if (!rtc->ops->read_alarm) { |
|---|
| 198 | 190 | err = -EINVAL; |
|---|
| 199 | | - else { |
|---|
| 191 | + } else { |
|---|
| 200 | 192 | alarm->enabled = 0; |
|---|
| 201 | 193 | alarm->pending = 0; |
|---|
| 202 | 194 | alarm->time.tm_sec = -1; |
|---|
| .. | .. |
|---|
| 224 | 216 | int first_time = 1; |
|---|
| 225 | 217 | time64_t t_now, t_alm; |
|---|
| 226 | 218 | enum { none, day, month, year } missing = none; |
|---|
| 227 | | - unsigned days; |
|---|
| 219 | + unsigned int days; |
|---|
| 228 | 220 | |
|---|
| 229 | 221 | /* The lower level RTC driver may return -1 in some fields, |
|---|
| 230 | 222 | * creating invalid alarm->time values, for reasons like: |
|---|
| .. | .. |
|---|
| 293 | 285 | return err; |
|---|
| 294 | 286 | |
|---|
| 295 | 287 | /* note that tm_sec is a "don't care" value here: */ |
|---|
| 296 | | - } while ( before.tm_min != now.tm_min |
|---|
| 297 | | - || before.tm_hour != now.tm_hour |
|---|
| 298 | | - || before.tm_mon != now.tm_mon |
|---|
| 299 | | - || before.tm_year != now.tm_year); |
|---|
| 288 | + } while (before.tm_min != now.tm_min || |
|---|
| 289 | + before.tm_hour != now.tm_hour || |
|---|
| 290 | + before.tm_mon != now.tm_mon || |
|---|
| 291 | + before.tm_year != now.tm_year); |
|---|
| 300 | 292 | |
|---|
| 301 | 293 | /* Fill in the missing alarm fields using the timestamp; we |
|---|
| 302 | 294 | * know there's at least one since alarm->time is invalid. |
|---|
| .. | .. |
|---|
| 313 | 305 | alarm->time.tm_mday = now.tm_mday; |
|---|
| 314 | 306 | missing = day; |
|---|
| 315 | 307 | } |
|---|
| 316 | | - if ((unsigned)alarm->time.tm_mon >= 12) { |
|---|
| 308 | + if ((unsigned int)alarm->time.tm_mon >= 12) { |
|---|
| 317 | 309 | alarm->time.tm_mon = now.tm_mon; |
|---|
| 318 | 310 | if (missing == none) |
|---|
| 319 | 311 | missing = month; |
|---|
| .. | .. |
|---|
| 338 | 330 | goto done; |
|---|
| 339 | 331 | |
|---|
| 340 | 332 | switch (missing) { |
|---|
| 341 | | - |
|---|
| 342 | 333 | /* 24 hour rollover ... if it's now 10am Monday, an alarm that |
|---|
| 343 | 334 | * that will trigger at 5am will do so at 5am Tuesday, which |
|---|
| 344 | 335 | * could also be in the next month or year. This is a common |
|---|
| .. | .. |
|---|
| 358 | 349 | case month: |
|---|
| 359 | 350 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month"); |
|---|
| 360 | 351 | do { |
|---|
| 361 | | - if (alarm->time.tm_mon < 11) |
|---|
| 352 | + if (alarm->time.tm_mon < 11) { |
|---|
| 362 | 353 | alarm->time.tm_mon++; |
|---|
| 363 | | - else { |
|---|
| 354 | + } else { |
|---|
| 364 | 355 | alarm->time.tm_mon = 0; |
|---|
| 365 | 356 | alarm->time.tm_year++; |
|---|
| 366 | 357 | } |
|---|
| 367 | 358 | days = rtc_month_days(alarm->time.tm_mon, |
|---|
| 368 | | - alarm->time.tm_year); |
|---|
| 359 | + alarm->time.tm_year); |
|---|
| 369 | 360 | } while (days < alarm->time.tm_mday); |
|---|
| 370 | 361 | break; |
|---|
| 371 | 362 | |
|---|
| .. | .. |
|---|
| 374 | 365 | dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); |
|---|
| 375 | 366 | do { |
|---|
| 376 | 367 | alarm->time.tm_year++; |
|---|
| 377 | | - } while (!is_leap_year(alarm->time.tm_year + 1900) |
|---|
| 378 | | - && rtc_valid_tm(&alarm->time) != 0); |
|---|
| 368 | + } while (!is_leap_year(alarm->time.tm_year + 1900) && |
|---|
| 369 | + rtc_valid_tm(&alarm->time) != 0); |
|---|
| 379 | 370 | break; |
|---|
| 380 | 371 | |
|---|
| 381 | 372 | default: |
|---|
| .. | .. |
|---|
| 385 | 376 | err = rtc_valid_tm(&alarm->time); |
|---|
| 386 | 377 | |
|---|
| 387 | 378 | done: |
|---|
| 388 | | - if (err) { |
|---|
| 389 | | - dev_warn(&rtc->dev, "invalid alarm value: %d-%d-%d %d:%d:%d\n", |
|---|
| 390 | | - alarm->time.tm_year + 1900, alarm->time.tm_mon + 1, |
|---|
| 391 | | - alarm->time.tm_mday, alarm->time.tm_hour, alarm->time.tm_min, |
|---|
| 392 | | - alarm->time.tm_sec); |
|---|
| 393 | | - } |
|---|
| 379 | + if (err) |
|---|
| 380 | + dev_warn(&rtc->dev, "invalid alarm value: %ptR\n", |
|---|
| 381 | + &alarm->time); |
|---|
| 394 | 382 | |
|---|
| 395 | 383 | return err; |
|---|
| 396 | 384 | } |
|---|
| .. | .. |
|---|
| 402 | 390 | err = mutex_lock_interruptible(&rtc->ops_lock); |
|---|
| 403 | 391 | if (err) |
|---|
| 404 | 392 | return err; |
|---|
| 405 | | - if (rtc->ops == NULL) |
|---|
| 393 | + if (!rtc->ops) { |
|---|
| 406 | 394 | err = -ENODEV; |
|---|
| 407 | | - else if (!rtc->ops->read_alarm) |
|---|
| 395 | + } else if (!rtc->ops->read_alarm) { |
|---|
| 408 | 396 | err = -EINVAL; |
|---|
| 409 | | - else { |
|---|
| 397 | + } else { |
|---|
| 410 | 398 | memset(alarm, 0, sizeof(struct rtc_wkalrm)); |
|---|
| 411 | 399 | alarm->enabled = rtc->aie_timer.enabled; |
|---|
| 412 | 400 | alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); |
|---|
| .. | .. |
|---|
| 515 | 503 | /* Alarm has to be enabled & in the future for us to enqueue it */ |
|---|
| 516 | 504 | if (alarm->enabled && (rtc_tm_to_ktime(now) < |
|---|
| 517 | 505 | rtc->aie_timer.node.expires)) { |
|---|
| 518 | | - |
|---|
| 519 | 506 | rtc->aie_timer.enabled = 1; |
|---|
| 520 | 507 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); |
|---|
| 521 | 508 | trace_rtc_timer_enqueue(&rtc->aie_timer); |
|---|
| .. | .. |
|---|
| 527 | 514 | |
|---|
| 528 | 515 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
|---|
| 529 | 516 | { |
|---|
| 530 | | - int err = mutex_lock_interruptible(&rtc->ops_lock); |
|---|
| 517 | + int err; |
|---|
| 518 | + |
|---|
| 519 | + err = mutex_lock_interruptible(&rtc->ops_lock); |
|---|
| 531 | 520 | if (err) |
|---|
| 532 | 521 | return err; |
|---|
| 533 | 522 | |
|---|
| .. | .. |
|---|
| 556 | 545 | |
|---|
| 557 | 546 | int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
|---|
| 558 | 547 | { |
|---|
| 559 | | - int err = mutex_lock_interruptible(&rtc->ops_lock); |
|---|
| 548 | + int rc = 0, err; |
|---|
| 549 | + |
|---|
| 550 | + err = mutex_lock_interruptible(&rtc->ops_lock); |
|---|
| 560 | 551 | if (err) |
|---|
| 561 | 552 | return err; |
|---|
| 562 | 553 | |
|---|
| .. | .. |
|---|
| 579 | 570 | struct rtc_time tm; |
|---|
| 580 | 571 | ktime_t now, onesec; |
|---|
| 581 | 572 | |
|---|
| 582 | | - __rtc_read_time(rtc, &tm); |
|---|
| 573 | + rc = __rtc_read_time(rtc, &tm); |
|---|
| 574 | + if (rc) |
|---|
| 575 | + goto out; |
|---|
| 583 | 576 | onesec = ktime_set(1, 0); |
|---|
| 584 | 577 | now = rtc_tm_to_ktime(tm); |
|---|
| 585 | 578 | rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); |
|---|
| 586 | 579 | rtc->uie_rtctimer.period = ktime_set(1, 0); |
|---|
| 587 | 580 | err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); |
|---|
| 588 | | - } else |
|---|
| 581 | + } else { |
|---|
| 589 | 582 | rtc_timer_remove(rtc, &rtc->uie_rtctimer); |
|---|
| 583 | + } |
|---|
| 590 | 584 | |
|---|
| 591 | 585 | out: |
|---|
| 592 | 586 | mutex_unlock(&rtc->ops_lock); |
|---|
| 587 | + |
|---|
| 588 | + /* |
|---|
| 589 | + * __rtc_read_time() failed, this probably means that the RTC time has |
|---|
| 590 | + * never been set or less probably there is a transient error on the |
|---|
| 591 | + * bus. In any case, avoid enabling emulation has this will fail when |
|---|
| 592 | + * reading the time too. |
|---|
| 593 | + */ |
|---|
| 594 | + if (rc) |
|---|
| 595 | + return rc; |
|---|
| 596 | + |
|---|
| 593 | 597 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
|---|
| 594 | 598 | /* |
|---|
| 595 | | - * Enable emulation if the driver did not provide |
|---|
| 596 | | - * the update_irq_enable function pointer or if returned |
|---|
| 597 | | - * -EINVAL to signal that it has been configured without |
|---|
| 598 | | - * interrupts or that are not available at the moment. |
|---|
| 599 | + * Enable emulation if the driver returned -EINVAL to signal that it has |
|---|
| 600 | + * been configured without interrupts or they are not available at the |
|---|
| 601 | + * moment. |
|---|
| 599 | 602 | */ |
|---|
| 600 | 603 | if (err == -EINVAL) |
|---|
| 601 | 604 | err = rtc_dev_update_irq_enable_emul(rtc, enabled); |
|---|
| 602 | 605 | #endif |
|---|
| 603 | 606 | return err; |
|---|
| 604 | | - |
|---|
| 605 | 607 | } |
|---|
| 606 | 608 | EXPORT_SYMBOL_GPL(rtc_update_irq_enable); |
|---|
| 607 | | - |
|---|
| 608 | 609 | |
|---|
| 609 | 610 | /** |
|---|
| 610 | 611 | * rtc_handle_legacy_irq - AIE, UIE and PIE event hook |
|---|
| 611 | 612 | * @rtc: pointer to the rtc device |
|---|
| 613 | + * @num: number of occurence of the event |
|---|
| 614 | + * @mode: type of the event, RTC_AF, RTC_UF of RTC_PF |
|---|
| 612 | 615 | * |
|---|
| 613 | 616 | * This function is called when an AIE, UIE or PIE mode interrupt |
|---|
| 614 | 617 | * has occurred (or been emulated). |
|---|
| 615 | 618 | * |
|---|
| 616 | | - * Triggers the registered irq_task function callback. |
|---|
| 617 | 619 | */ |
|---|
| 618 | 620 | void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) |
|---|
| 619 | 621 | { |
|---|
| .. | .. |
|---|
| 621 | 623 | |
|---|
| 622 | 624 | /* mark one irq of the appropriate mode */ |
|---|
| 623 | 625 | spin_lock_irqsave(&rtc->irq_lock, flags); |
|---|
| 624 | | - rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); |
|---|
| 626 | + rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF | mode); |
|---|
| 625 | 627 | spin_unlock_irqrestore(&rtc->irq_lock, flags); |
|---|
| 626 | 628 | |
|---|
| 627 | 629 | wake_up_interruptible(&rtc->irq_queue); |
|---|
| 628 | 630 | kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); |
|---|
| 629 | 631 | } |
|---|
| 630 | 632 | |
|---|
| 631 | | - |
|---|
| 632 | 633 | /** |
|---|
| 633 | 634 | * rtc_aie_update_irq - AIE mode rtctimer hook |
|---|
| 634 | | - * @private: pointer to the rtc_device |
|---|
| 635 | + * @rtc: pointer to the rtc_device |
|---|
| 635 | 636 | * |
|---|
| 636 | 637 | * This functions is called when the aie_timer expires. |
|---|
| 637 | 638 | */ |
|---|
| 638 | | -void rtc_aie_update_irq(void *private) |
|---|
| 639 | +void rtc_aie_update_irq(struct rtc_device *rtc) |
|---|
| 639 | 640 | { |
|---|
| 640 | | - struct rtc_device *rtc = (struct rtc_device *)private; |
|---|
| 641 | 641 | rtc_handle_legacy_irq(rtc, 1, RTC_AF); |
|---|
| 642 | 642 | } |
|---|
| 643 | 643 | |
|---|
| 644 | | - |
|---|
| 645 | 644 | /** |
|---|
| 646 | 645 | * rtc_uie_update_irq - UIE mode rtctimer hook |
|---|
| 647 | | - * @private: pointer to the rtc_device |
|---|
| 646 | + * @rtc: pointer to the rtc_device |
|---|
| 648 | 647 | * |
|---|
| 649 | 648 | * This functions is called when the uie_timer expires. |
|---|
| 650 | 649 | */ |
|---|
| 651 | | -void rtc_uie_update_irq(void *private) |
|---|
| 650 | +void rtc_uie_update_irq(struct rtc_device *rtc) |
|---|
| 652 | 651 | { |
|---|
| 653 | | - struct rtc_device *rtc = (struct rtc_device *)private; |
|---|
| 654 | 652 | rtc_handle_legacy_irq(rtc, 1, RTC_UF); |
|---|
| 655 | 653 | } |
|---|
| 656 | | - |
|---|
| 657 | 654 | |
|---|
| 658 | 655 | /** |
|---|
| 659 | 656 | * rtc_pie_update_irq - PIE mode hrtimer hook |
|---|
| .. | .. |
|---|
| 667 | 664 | { |
|---|
| 668 | 665 | struct rtc_device *rtc; |
|---|
| 669 | 666 | ktime_t period; |
|---|
| 670 | | - int count; |
|---|
| 667 | + u64 count; |
|---|
| 668 | + |
|---|
| 671 | 669 | rtc = container_of(timer, struct rtc_device, pie_timer); |
|---|
| 672 | 670 | |
|---|
| 673 | 671 | period = NSEC_PER_SEC / rtc->irq_freq; |
|---|
| .. | .. |
|---|
| 686 | 684 | * Context: any |
|---|
| 687 | 685 | */ |
|---|
| 688 | 686 | void rtc_update_irq(struct rtc_device *rtc, |
|---|
| 689 | | - unsigned long num, unsigned long events) |
|---|
| 687 | + unsigned long num, unsigned long events) |
|---|
| 690 | 688 | { |
|---|
| 691 | 689 | if (IS_ERR_OR_NULL(rtc)) |
|---|
| 692 | 690 | return; |
|---|
| .. | .. |
|---|
| 696 | 694 | } |
|---|
| 697 | 695 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
|---|
| 698 | 696 | |
|---|
| 699 | | -static int __rtc_match(struct device *dev, const void *data) |
|---|
| 700 | | -{ |
|---|
| 701 | | - const char *name = data; |
|---|
| 702 | | - |
|---|
| 703 | | - if (strcmp(dev_name(dev), name) == 0) |
|---|
| 704 | | - return 1; |
|---|
| 705 | | - return 0; |
|---|
| 706 | | -} |
|---|
| 707 | | - |
|---|
| 708 | 697 | struct rtc_device *rtc_class_open(const char *name) |
|---|
| 709 | 698 | { |
|---|
| 710 | 699 | struct device *dev; |
|---|
| 711 | 700 | struct rtc_device *rtc = NULL; |
|---|
| 712 | 701 | |
|---|
| 713 | | - dev = class_find_device(rtc_class, NULL, name, __rtc_match); |
|---|
| 702 | + dev = class_find_device_by_name(rtc_class, name); |
|---|
| 714 | 703 | if (dev) |
|---|
| 715 | 704 | rtc = to_rtc_device(dev); |
|---|
| 716 | 705 | |
|---|
| .. | .. |
|---|
| 758 | 747 | /** |
|---|
| 759 | 748 | * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs |
|---|
| 760 | 749 | * @rtc: the rtc device |
|---|
| 761 | | - * @task: currently registered with rtc_irq_register() |
|---|
| 762 | 750 | * @enabled: true to enable periodic IRQs |
|---|
| 763 | 751 | * Context: any |
|---|
| 764 | 752 | * |
|---|
| .. | .. |
|---|
| 781 | 769 | /** |
|---|
| 782 | 770 | * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ |
|---|
| 783 | 771 | * @rtc: the rtc device |
|---|
| 784 | | - * @task: currently registered with rtc_irq_register() |
|---|
| 785 | 772 | * @freq: positive frequency |
|---|
| 786 | 773 | * Context: any |
|---|
| 787 | 774 | * |
|---|
| .. | .. |
|---|
| 805 | 792 | |
|---|
| 806 | 793 | /** |
|---|
| 807 | 794 | * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue |
|---|
| 808 | | - * @rtc rtc device |
|---|
| 809 | | - * @timer timer being added. |
|---|
| 795 | + * @rtc: rtc device |
|---|
| 796 | + * @timer: timer being added. |
|---|
| 810 | 797 | * |
|---|
| 811 | 798 | * Enqueues a timer onto the rtc devices timerqueue and sets |
|---|
| 812 | 799 | * the next alarm event appropriately. |
|---|
| .. | .. |
|---|
| 820 | 807 | struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); |
|---|
| 821 | 808 | struct rtc_time tm; |
|---|
| 822 | 809 | ktime_t now; |
|---|
| 810 | + int err; |
|---|
| 811 | + |
|---|
| 812 | + err = __rtc_read_time(rtc, &tm); |
|---|
| 813 | + if (err) |
|---|
| 814 | + return err; |
|---|
| 823 | 815 | |
|---|
| 824 | 816 | timer->enabled = 1; |
|---|
| 825 | | - __rtc_read_time(rtc, &tm); |
|---|
| 826 | 817 | now = rtc_tm_to_ktime(tm); |
|---|
| 827 | 818 | |
|---|
| 828 | 819 | /* Skip over expired timers */ |
|---|
| .. | .. |
|---|
| 836 | 827 | trace_rtc_timer_enqueue(timer); |
|---|
| 837 | 828 | if (!next || ktime_before(timer->node.expires, next->expires)) { |
|---|
| 838 | 829 | struct rtc_wkalrm alarm; |
|---|
| 839 | | - int err; |
|---|
| 830 | + |
|---|
| 840 | 831 | alarm.time = rtc_ktime_to_tm(timer->node.expires); |
|---|
| 841 | 832 | alarm.enabled = 1; |
|---|
| 842 | 833 | err = __rtc_set_alarm(rtc, &alarm); |
|---|
| .. | .. |
|---|
| 864 | 855 | |
|---|
| 865 | 856 | /** |
|---|
| 866 | 857 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue |
|---|
| 867 | | - * @rtc rtc device |
|---|
| 868 | | - * @timer timer being removed. |
|---|
| 858 | + * @rtc: rtc device |
|---|
| 859 | + * @timer: timer being removed. |
|---|
| 869 | 860 | * |
|---|
| 870 | 861 | * Removes a timer onto the rtc devices timerqueue and sets |
|---|
| 871 | 862 | * the next alarm event appropriately. |
|---|
| .. | .. |
|---|
| 877 | 868 | static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) |
|---|
| 878 | 869 | { |
|---|
| 879 | 870 | struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); |
|---|
| 871 | + |
|---|
| 880 | 872 | timerqueue_del(&rtc->timerqueue, &timer->node); |
|---|
| 881 | 873 | trace_rtc_timer_dequeue(timer); |
|---|
| 882 | 874 | timer->enabled = 0; |
|---|
| 883 | 875 | if (next == &timer->node) { |
|---|
| 884 | 876 | struct rtc_wkalrm alarm; |
|---|
| 885 | 877 | int err; |
|---|
| 878 | + |
|---|
| 886 | 879 | next = timerqueue_getnext(&rtc->timerqueue); |
|---|
| 887 | 880 | if (!next) { |
|---|
| 888 | 881 | rtc_alarm_disable(rtc); |
|---|
| .. | .. |
|---|
| 900 | 893 | |
|---|
| 901 | 894 | /** |
|---|
| 902 | 895 | * rtc_timer_do_work - Expires rtc timers |
|---|
| 903 | | - * @rtc rtc device |
|---|
| 904 | | - * @timer timer being removed. |
|---|
| 896 | + * @work: work item |
|---|
| 905 | 897 | * |
|---|
| 906 | 898 | * Expires rtc timers. Reprograms next alarm event if needed. |
|---|
| 907 | 899 | * Called via worktask. |
|---|
| .. | .. |
|---|
| 932 | 924 | trace_rtc_timer_dequeue(timer); |
|---|
| 933 | 925 | timer->enabled = 0; |
|---|
| 934 | 926 | if (timer->func) |
|---|
| 935 | | - timer->func(timer->private_data); |
|---|
| 927 | + timer->func(timer->rtc); |
|---|
| 936 | 928 | |
|---|
| 937 | 929 | trace_rtc_timer_fired(timer); |
|---|
| 938 | 930 | /* Re-add/fwd periodic timers */ |
|---|
| .. | .. |
|---|
| 955 | 947 | alarm.enabled = 1; |
|---|
| 956 | 948 | reprogram: |
|---|
| 957 | 949 | err = __rtc_set_alarm(rtc, &alarm); |
|---|
| 958 | | - if (err == -ETIME) |
|---|
| 950 | + if (err == -ETIME) { |
|---|
| 959 | 951 | goto again; |
|---|
| 960 | | - else if (err) { |
|---|
| 952 | + } else if (err) { |
|---|
| 961 | 953 | if (retry-- > 0) |
|---|
| 962 | 954 | goto reprogram; |
|---|
| 963 | 955 | |
|---|
| .. | .. |
|---|
| 968 | 960 | dev_err(&rtc->dev, "__rtc_set_alarm: err=%d\n", err); |
|---|
| 969 | 961 | goto again; |
|---|
| 970 | 962 | } |
|---|
| 971 | | - } else |
|---|
| 963 | + } else { |
|---|
| 972 | 964 | rtc_alarm_disable(rtc); |
|---|
| 965 | + } |
|---|
| 973 | 966 | |
|---|
| 974 | 967 | pm_relax(rtc->dev.parent); |
|---|
| 975 | 968 | mutex_unlock(&rtc->ops_lock); |
|---|
| 976 | 969 | } |
|---|
| 977 | 970 | |
|---|
| 978 | | - |
|---|
| 979 | 971 | /* rtc_timer_init - Initializes an rtc_timer |
|---|
| 980 | 972 | * @timer: timer to be intiialized |
|---|
| 981 | 973 | * @f: function pointer to be called when timer fires |
|---|
| 982 | | - * @data: private data passed to function pointer |
|---|
| 974 | + * @rtc: pointer to the rtc_device |
|---|
| 983 | 975 | * |
|---|
| 984 | 976 | * Kernel interface to initializing an rtc_timer. |
|---|
| 985 | 977 | */ |
|---|
| 986 | | -void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data) |
|---|
| 978 | +void rtc_timer_init(struct rtc_timer *timer, void (*f)(struct rtc_device *r), |
|---|
| 979 | + struct rtc_device *rtc) |
|---|
| 987 | 980 | { |
|---|
| 988 | 981 | timerqueue_init(&timer->node); |
|---|
| 989 | 982 | timer->enabled = 0; |
|---|
| 990 | 983 | timer->func = f; |
|---|
| 991 | | - timer->private_data = data; |
|---|
| 984 | + timer->rtc = rtc; |
|---|
| 992 | 985 | } |
|---|
| 993 | 986 | |
|---|
| 994 | 987 | /* rtc_timer_start - Sets an rtc_timer to fire in the future |
|---|
| .. | .. |
|---|
| 1000 | 993 | * Kernel interface to set an rtc_timer |
|---|
| 1001 | 994 | */ |
|---|
| 1002 | 995 | int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer, |
|---|
| 1003 | | - ktime_t expires, ktime_t period) |
|---|
| 996 | + ktime_t expires, ktime_t period) |
|---|
| 1004 | 997 | { |
|---|
| 1005 | 998 | int ret = 0; |
|---|
| 999 | + |
|---|
| 1006 | 1000 | mutex_lock(&rtc->ops_lock); |
|---|
| 1007 | 1001 | if (timer->enabled) |
|---|
| 1008 | 1002 | rtc_timer_remove(rtc, timer); |
|---|
| .. | .. |
|---|
| 1032 | 1026 | |
|---|
| 1033 | 1027 | /** |
|---|
| 1034 | 1028 | * rtc_read_offset - Read the amount of rtc offset in parts per billion |
|---|
| 1035 | | - * @ rtc: rtc device to be used |
|---|
| 1036 | | - * @ offset: the offset in parts per billion |
|---|
| 1029 | + * @rtc: rtc device to be used |
|---|
| 1030 | + * @offset: the offset in parts per billion |
|---|
| 1037 | 1031 | * |
|---|
| 1038 | 1032 | * see below for details. |
|---|
| 1039 | 1033 | * |
|---|
| .. | .. |
|---|
| 1061 | 1055 | |
|---|
| 1062 | 1056 | /** |
|---|
| 1063 | 1057 | * rtc_set_offset - Adjusts the duration of the average second |
|---|
| 1064 | | - * @ rtc: rtc device to be used |
|---|
| 1065 | | - * @ offset: the offset in parts per billion |
|---|
| 1058 | + * @rtc: rtc device to be used |
|---|
| 1059 | + * @offset: the offset in parts per billion |
|---|
| 1066 | 1060 | * |
|---|
| 1067 | 1061 | * Some rtc's allow an adjustment to the average duration of a second |
|---|
| 1068 | 1062 | * to compensate for differences in the actual clock rate due to temperature, |
|---|