diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-20 19:30:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-08-20 19:30:27 -0400 |
commit | bfebeb16722d93caf7870b63aa7d094b6843479a (patch) | |
tree | 48cfc8044f7604b99a127a3c0667ff20f57e22ef /drivers/rtc/interface.c | |
parent | 3933ec73cd9bbff4a98259d0eae606af4e2850a2 (diff) | |
parent | 6b583a64fd1e019fd01626b46892ebf2361951c5 (diff) |
Merge tag 'rtc-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"It is now possible to add custom sysfs attributes while avoiding a
possible race condition. Unused code has been removed resulting in a
nice reduction of the code base. And more drivers have been switched
to SPDX by their maintainers.
Summary:
Subsystem:
- new helpers to add custom sysfs attributes
- struct rtc_task removal along with rtc_irq_[un]register()
- rtc_irq_set_state and rtc_irq_set_freq are not exported anymore
Drivers:
- armada38x: reset after rtc power loss
- ds1307: now supports m41t11
- isl1208: now supports isl1219 and tamper detection
- pcf2127: internal SRAM support"
* tag 'rtc-4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (34 commits)
rtc: ds1307: simplify hwmon config
rtc: s5m: Add SPDX license identifier
rtc: maxim: Add SPDX license identifiers
rtc: isl1219: add device tree documentation
rtc: isl1208: set ev-evienb bit from device tree
rtc: isl1208: Add "evdet" interrupt source for isl1219
rtc: isl1208: add support for isl1219 with tamper detection
rtc: sysfs: facilitate attribute add to rtc device
rtc: remove struct rtc_task
char: rtc: remove task handling
rtc: pcf85063: preserve control register value between stop and start
rtc: sh: remove unused variable rtc_dev
rtc: unexport rtc_irq_set_*
rtc: simplify rtc_irq_set_state/rtc_irq_set_freq
rtc: remove irq_task and irq_task_lock
rtc: remove rtc_irq_register/rtc_irq_unregister
rtc: sh: remove dead code
rtc: sa1100: don't set PIE frequency
rtc: ds1307: support m41t11 variant
rtc: ds1307: fix data pointer to m41t0
...
Diffstat (limited to 'drivers/rtc/interface.c')
-rw-r--r-- | drivers/rtc/interface.c | 97 |
1 files changed, 16 insertions, 81 deletions
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index bac1eeb3d312..3d577e259e91 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -607,12 +607,6 @@ void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) | |||
607 | rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); | 607 | rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); |
608 | spin_unlock_irqrestore(&rtc->irq_lock, flags); | 608 | spin_unlock_irqrestore(&rtc->irq_lock, flags); |
609 | 609 | ||
610 | /* call the task func */ | ||
611 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | ||
612 | if (rtc->irq_task) | ||
613 | rtc->irq_task->func(rtc->irq_task->private_data); | ||
614 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
615 | |||
616 | wake_up_interruptible(&rtc->irq_queue); | 610 | wake_up_interruptible(&rtc->irq_queue); |
617 | kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); | 611 | kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); |
618 | } | 612 | } |
@@ -721,39 +715,6 @@ void rtc_class_close(struct rtc_device *rtc) | |||
721 | } | 715 | } |
722 | EXPORT_SYMBOL_GPL(rtc_class_close); | 716 | EXPORT_SYMBOL_GPL(rtc_class_close); |
723 | 717 | ||
724 | int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) | ||
725 | { | ||
726 | int retval = -EBUSY; | ||
727 | |||
728 | if (task == NULL || task->func == NULL) | ||
729 | return -EINVAL; | ||
730 | |||
731 | /* Cannot register while the char dev is in use */ | ||
732 | if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) | ||
733 | return -EBUSY; | ||
734 | |||
735 | spin_lock_irq(&rtc->irq_task_lock); | ||
736 | if (rtc->irq_task == NULL) { | ||
737 | rtc->irq_task = task; | ||
738 | retval = 0; | ||
739 | } | ||
740 | spin_unlock_irq(&rtc->irq_task_lock); | ||
741 | |||
742 | clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); | ||
743 | |||
744 | return retval; | ||
745 | } | ||
746 | EXPORT_SYMBOL_GPL(rtc_irq_register); | ||
747 | |||
748 | void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) | ||
749 | { | ||
750 | spin_lock_irq(&rtc->irq_task_lock); | ||
751 | if (rtc->irq_task == task) | ||
752 | rtc->irq_task = NULL; | ||
753 | spin_unlock_irq(&rtc->irq_task_lock); | ||
754 | } | ||
755 | EXPORT_SYMBOL_GPL(rtc_irq_unregister); | ||
756 | |||
757 | static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) | 718 | static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) |
758 | { | 719 | { |
759 | /* | 720 | /* |
@@ -785,71 +746,45 @@ static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled) | |||
785 | * Context: any | 746 | * Context: any |
786 | * | 747 | * |
787 | * Note that rtc_irq_set_freq() should previously have been used to | 748 | * Note that rtc_irq_set_freq() should previously have been used to |
788 | * specify the desired frequency of periodic IRQ task->func() callbacks. | 749 | * specify the desired frequency of periodic IRQ. |
789 | */ | 750 | */ |
790 | int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled) | 751 | int rtc_irq_set_state(struct rtc_device *rtc, int enabled) |
791 | { | 752 | { |
792 | int err = 0; | 753 | int err = 0; |
793 | unsigned long flags; | ||
794 | 754 | ||
795 | retry: | 755 | while (rtc_update_hrtimer(rtc, enabled) < 0) |
796 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 756 | cpu_relax(); |
797 | if (rtc->irq_task != NULL && task == NULL) | 757 | |
798 | err = -EBUSY; | 758 | rtc->pie_enabled = enabled; |
799 | else if (rtc->irq_task != task) | ||
800 | err = -EACCES; | ||
801 | else { | ||
802 | if (rtc_update_hrtimer(rtc, enabled) < 0) { | ||
803 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
804 | cpu_relax(); | ||
805 | goto retry; | ||
806 | } | ||
807 | rtc->pie_enabled = enabled; | ||
808 | } | ||
809 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
810 | 759 | ||
811 | trace_rtc_irq_set_state(enabled, err); | 760 | trace_rtc_irq_set_state(enabled, err); |
812 | return err; | 761 | return err; |
813 | } | 762 | } |
814 | EXPORT_SYMBOL_GPL(rtc_irq_set_state); | ||
815 | 763 | ||
816 | /** | 764 | /** |
817 | * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ | 765 | * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ |
818 | * @rtc: the rtc device | 766 | * @rtc: the rtc device |
819 | * @task: currently registered with rtc_irq_register() | 767 | * @task: currently registered with rtc_irq_register() |
820 | * @freq: positive frequency with which task->func() will be called | 768 | * @freq: positive frequency |
821 | * Context: any | 769 | * Context: any |
822 | * | 770 | * |
823 | * Note that rtc_irq_set_state() is used to enable or disable the | 771 | * Note that rtc_irq_set_state() is used to enable or disable the |
824 | * periodic IRQs. | 772 | * periodic IRQs. |
825 | */ | 773 | */ |
826 | int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) | 774 | int rtc_irq_set_freq(struct rtc_device *rtc, int freq) |
827 | { | 775 | { |
828 | int err = 0; | 776 | int err = 0; |
829 | unsigned long flags; | ||
830 | 777 | ||
831 | if (freq <= 0 || freq > RTC_MAX_FREQ) | 778 | if (freq <= 0 || freq > RTC_MAX_FREQ) |
832 | return -EINVAL; | 779 | return -EINVAL; |
833 | retry: | 780 | |
834 | spin_lock_irqsave(&rtc->irq_task_lock, flags); | 781 | rtc->irq_freq = freq; |
835 | if (rtc->irq_task != NULL && task == NULL) | 782 | while (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) |
836 | err = -EBUSY; | 783 | cpu_relax(); |
837 | else if (rtc->irq_task != task) | ||
838 | err = -EACCES; | ||
839 | else { | ||
840 | rtc->irq_freq = freq; | ||
841 | if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) { | ||
842 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
843 | cpu_relax(); | ||
844 | goto retry; | ||
845 | } | ||
846 | } | ||
847 | spin_unlock_irqrestore(&rtc->irq_task_lock, flags); | ||
848 | 784 | ||
849 | trace_rtc_irq_set_freq(freq, err); | 785 | trace_rtc_irq_set_freq(freq, err); |
850 | return err; | 786 | return err; |
851 | } | 787 | } |
852 | EXPORT_SYMBOL_GPL(rtc_irq_set_freq); | ||
853 | 788 | ||
854 | /** | 789 | /** |
855 | * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue | 790 | * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue |
@@ -979,8 +914,8 @@ again: | |||
979 | timerqueue_del(&rtc->timerqueue, &timer->node); | 914 | timerqueue_del(&rtc->timerqueue, &timer->node); |
980 | trace_rtc_timer_dequeue(timer); | 915 | trace_rtc_timer_dequeue(timer); |
981 | timer->enabled = 0; | 916 | timer->enabled = 0; |
982 | if (timer->task.func) | 917 | if (timer->func) |
983 | timer->task.func(timer->task.private_data); | 918 | timer->func(timer->private_data); |
984 | 919 | ||
985 | trace_rtc_timer_fired(timer); | 920 | trace_rtc_timer_fired(timer); |
986 | /* Re-add/fwd periodic timers */ | 921 | /* Re-add/fwd periodic timers */ |
@@ -1035,8 +970,8 @@ void rtc_timer_init(struct rtc_timer *timer, void (*f)(void *p), void *data) | |||
1035 | { | 970 | { |
1036 | timerqueue_init(&timer->node); | 971 | timerqueue_init(&timer->node); |
1037 | timer->enabled = 0; | 972 | timer->enabled = 0; |
1038 | timer->task.func = f; | 973 | timer->func = f; |
1039 | timer->task.private_data = data; | 974 | timer->private_data = data; |
1040 | } | 975 | } |
1041 | 976 | ||
1042 | /* rtc_timer_start - Sets an rtc_timer to fire in the future | 977 | /* rtc_timer_start - Sets an rtc_timer to fire in the future |