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 | |
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
...
28 files changed, 524 insertions, 971 deletions
diff --git a/Documentation/devicetree/bindings/rtc/isil,isl1219.txt b/Documentation/devicetree/bindings/rtc/isil,isl1219.txt new file mode 100644 index 000000000000..c3efd48e91c2 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/isil,isl1219.txt | |||
@@ -0,0 +1,29 @@ | |||
1 | Intersil ISL1219 I2C RTC/Alarm chip with event in | ||
2 | |||
3 | ISL1219 has additional pins EVIN and #EVDET for tamper detection. | ||
4 | |||
5 | Required properties supported by the device: | ||
6 | |||
7 | - "compatible": must be "isil,isl1219" | ||
8 | - "reg": I2C bus address of the device | ||
9 | |||
10 | Optional properties: | ||
11 | |||
12 | - "interrupt-names": list which may contains "irq" and "evdet" | ||
13 | - "interrupts": list of interrupts for "irq" and "evdet" | ||
14 | - "isil,ev-evienb": if present EV.EVIENB bit is set to the specified | ||
15 | value for proper operation. | ||
16 | |||
17 | |||
18 | Example isl1219 node with #IRQ pin connected to SoC gpio1 pin12 | ||
19 | and #EVDET pin connected to SoC gpio2 pin 24: | ||
20 | |||
21 | isl1219: rtc@68 { | ||
22 | compatible = "isil,isl1219"; | ||
23 | reg = <0x68>; | ||
24 | interrupt-names = "irq", "evdet"; | ||
25 | interrupts-extended = <&gpio1 12 IRQ_TYPE_EDGE_FALLING>, | ||
26 | <&gpio2 24 IRQ_TYPE_EDGE_FALLING>; | ||
27 | isil,ev-evienb = <1>; | ||
28 | }; | ||
29 | |||
diff --git a/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt index 226cc93df875..eebfbe04207a 100644 --- a/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt +++ b/Documentation/devicetree/bindings/rtc/rtc-ds1307.txt | |||
@@ -13,6 +13,7 @@ Required properties: | |||
13 | "maxim,ds3231", | 13 | "maxim,ds3231", |
14 | "st,m41t0", | 14 | "st,m41t0", |
15 | "st,m41t00", | 15 | "st,m41t00", |
16 | "st,m41t11", | ||
16 | "microchip,mcp7940x", | 17 | "microchip,mcp7940x", |
17 | "microchip,mcp7941x", | 18 | "microchip,mcp7941x", |
18 | "pericom,pt7c4338", | 19 | "pericom,pt7c4338", |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index 94fedeeec035..4948c8bda6b1 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -193,14 +193,6 @@ static unsigned long rtc_freq; /* Current periodic IRQ rate */ | |||
193 | static unsigned long rtc_irq_data; /* our output to the world */ | 193 | static unsigned long rtc_irq_data; /* our output to the world */ |
194 | static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ | 194 | static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ |
195 | 195 | ||
196 | #ifdef RTC_IRQ | ||
197 | /* | ||
198 | * rtc_task_lock nests inside rtc_lock. | ||
199 | */ | ||
200 | static DEFINE_SPINLOCK(rtc_task_lock); | ||
201 | static rtc_task_t *rtc_callback; | ||
202 | #endif | ||
203 | |||
204 | /* | 196 | /* |
205 | * If this driver ever becomes modularised, it will be really nice | 197 | * If this driver ever becomes modularised, it will be really nice |
206 | * to make the epoch retain its value across module reload... | 198 | * to make the epoch retain its value across module reload... |
@@ -264,11 +256,6 @@ static irqreturn_t rtc_interrupt(int irq, void *dev_id) | |||
264 | 256 | ||
265 | spin_unlock(&rtc_lock); | 257 | spin_unlock(&rtc_lock); |
266 | 258 | ||
267 | /* Now do the rest of the actions */ | ||
268 | spin_lock(&rtc_task_lock); | ||
269 | if (rtc_callback) | ||
270 | rtc_callback->func(rtc_callback->private_data); | ||
271 | spin_unlock(&rtc_task_lock); | ||
272 | wake_up_interruptible(&rtc_wait); | 259 | wake_up_interruptible(&rtc_wait); |
273 | 260 | ||
274 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); | 261 | kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index a2ba5db36145..7d7be60a2413 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -244,15 +244,6 @@ config RTC_DRV_DS1307 | |||
244 | This driver can also be built as a module. If so, the module | 244 | This driver can also be built as a module. If so, the module |
245 | will be called rtc-ds1307. | 245 | will be called rtc-ds1307. |
246 | 246 | ||
247 | config RTC_DRV_DS1307_HWMON | ||
248 | bool "HWMON support for rtc-ds1307" | ||
249 | depends on RTC_DRV_DS1307 && HWMON | ||
250 | depends on !(RTC_DRV_DS1307=y && HWMON=m) | ||
251 | default y | ||
252 | help | ||
253 | Say Y here if you want to expose temperature sensor data on | ||
254 | rtc-ds1307 (only DS3231) | ||
255 | |||
256 | config RTC_DRV_DS1307_CENTURY | 247 | config RTC_DRV_DS1307_CENTURY |
257 | bool "Century bit support for rtc-ds1307" | 248 | bool "Century bit support for rtc-ds1307" |
258 | depends on RTC_DRV_DS1307 | 249 | depends on RTC_DRV_DS1307 |
@@ -1027,18 +1018,6 @@ config RTC_DS1685_PROC_REGS | |||
1027 | 1018 | ||
1028 | Unless you are debugging this driver, choose N. | 1019 | Unless you are debugging this driver, choose N. |
1029 | 1020 | ||
1030 | config RTC_DS1685_SYSFS_REGS | ||
1031 | bool "SysFS access to RTC register bits" | ||
1032 | depends on RTC_DRV_DS1685_FAMILY && SYSFS | ||
1033 | help | ||
1034 | Enable this to provide access to the RTC control register bits | ||
1035 | in /sys. Some of the bits are read-write, others are read-only. | ||
1036 | |||
1037 | Keep in mind that reading Control C's bits automatically clears | ||
1038 | all pending IRQ flags - this can cause lost interrupts. | ||
1039 | |||
1040 | If you know that you need access to these bits, choose Y, Else N. | ||
1041 | |||
1042 | config RTC_DRV_DS1742 | 1021 | config RTC_DRV_DS1742 |
1043 | tristate "Maxim/Dallas DS1742/1743" | 1022 | tristate "Maxim/Dallas DS1742/1743" |
1044 | depends on HAS_IOMEM | 1023 | depends on HAS_IOMEM |
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index d37588f08055..0fca4d74c76b 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -68,7 +68,7 @@ static int rtc_suspend(struct device *dev) | |||
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | getnstimeofday64(&old_system); | 71 | ktime_get_real_ts64(&old_system); |
72 | old_rtc.tv_sec = rtc_tm_to_time64(&tm); | 72 | old_rtc.tv_sec = rtc_tm_to_time64(&tm); |
73 | 73 | ||
74 | 74 | ||
@@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev) | |||
110 | return 0; | 110 | return 0; |
111 | 111 | ||
112 | /* snapshot the current rtc and system time at resume */ | 112 | /* snapshot the current rtc and system time at resume */ |
113 | getnstimeofday64(&new_system); | 113 | ktime_get_real_ts64(&new_system); |
114 | err = rtc_read_time(rtc, &tm); | 114 | err = rtc_read_time(rtc, &tm); |
115 | if (err < 0) { | 115 | if (err < 0) { |
116 | pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev)); | 116 | pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev)); |
@@ -172,7 +172,6 @@ static struct rtc_device *rtc_allocate_device(void) | |||
172 | 172 | ||
173 | mutex_init(&rtc->ops_lock); | 173 | mutex_init(&rtc->ops_lock); |
174 | spin_lock_init(&rtc->irq_lock); | 174 | spin_lock_init(&rtc->irq_lock); |
175 | spin_lock_init(&rtc->irq_task_lock); | ||
176 | init_waitqueue_head(&rtc->irq_queue); | 175 | init_waitqueue_head(&rtc->irq_queue); |
177 | 176 | ||
178 | /* Init timerqueue */ | 177 | /* Init timerqueue */ |
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 |
diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 1e4978c96ffd..bde53c8ccee2 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #define RTC_IRQ_FREQ_1HZ BIT(2) | 30 | #define RTC_IRQ_FREQ_1HZ BIT(2) |
31 | #define RTC_CCR 0x18 | 31 | #define RTC_CCR 0x18 |
32 | #define RTC_CCR_MODE BIT(15) | 32 | #define RTC_CCR_MODE BIT(15) |
33 | #define RTC_CONF_TEST 0x1C | ||
34 | #define RTC_NOMINAL_TIMING BIT(13) | ||
33 | 35 | ||
34 | #define RTC_TIME 0xC | 36 | #define RTC_TIME 0xC |
35 | #define RTC_ALARM1 0x10 | 37 | #define RTC_ALARM1 0x10 |
@@ -75,6 +77,7 @@ struct armada38x_rtc { | |||
75 | void __iomem *regs_soc; | 77 | void __iomem *regs_soc; |
76 | spinlock_t lock; | 78 | spinlock_t lock; |
77 | int irq; | 79 | int irq; |
80 | bool initialized; | ||
78 | struct value_to_freq *val_to_freq; | 81 | struct value_to_freq *val_to_freq; |
79 | struct armada38x_rtc_data *data; | 82 | struct armada38x_rtc_data *data; |
80 | }; | 83 | }; |
@@ -226,6 +229,23 @@ static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
226 | return 0; | 229 | return 0; |
227 | } | 230 | } |
228 | 231 | ||
232 | static void armada38x_rtc_reset(struct armada38x_rtc *rtc) | ||
233 | { | ||
234 | u32 reg; | ||
235 | |||
236 | reg = rtc->data->read_rtc_reg(rtc, RTC_CONF_TEST); | ||
237 | /* If bits [7:0] are non-zero, assume RTC was uninitialized */ | ||
238 | if (reg & 0xff) { | ||
239 | rtc_delayed_write(0, rtc, RTC_CONF_TEST); | ||
240 | msleep(500); /* Oscillator startup time */ | ||
241 | rtc_delayed_write(0, rtc, RTC_TIME); | ||
242 | rtc_delayed_write(SOC_RTC_ALARM1 | SOC_RTC_ALARM2, rtc, | ||
243 | RTC_STATUS); | ||
244 | rtc_delayed_write(RTC_NOMINAL_TIMING, rtc, RTC_CCR); | ||
245 | } | ||
246 | rtc->initialized = true; | ||
247 | } | ||
248 | |||
229 | static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) | 249 | static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) |
230 | { | 250 | { |
231 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); | 251 | struct armada38x_rtc *rtc = dev_get_drvdata(dev); |
@@ -237,6 +257,9 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
237 | if (ret) | 257 | if (ret) |
238 | goto out; | 258 | goto out; |
239 | 259 | ||
260 | if (!rtc->initialized) | ||
261 | armada38x_rtc_reset(rtc); | ||
262 | |||
240 | spin_lock_irqsave(&rtc->lock, flags); | 263 | spin_lock_irqsave(&rtc->lock, flags); |
241 | rtc_delayed_write(time, rtc, RTC_TIME); | 264 | rtc_delayed_write(time, rtc, RTC_TIME); |
242 | spin_unlock_irqrestore(&rtc->lock, flags); | 265 | spin_unlock_irqrestore(&rtc->lock, flags); |
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c index d768f6747961..113493b52149 100644 --- a/drivers/rtc/rtc-bq4802.c +++ b/drivers/rtc/rtc-bq4802.c | |||
@@ -162,6 +162,10 @@ static int bq4802_probe(struct platform_device *pdev) | |||
162 | } else if (p->r->flags & IORESOURCE_MEM) { | 162 | } else if (p->r->flags & IORESOURCE_MEM) { |
163 | p->regs = devm_ioremap(&pdev->dev, p->r->start, | 163 | p->regs = devm_ioremap(&pdev->dev, p->r->start, |
164 | resource_size(p->r)); | 164 | resource_size(p->r)); |
165 | if (!p->regs){ | ||
166 | err = -ENOMEM; | ||
167 | goto out; | ||
168 | } | ||
165 | p->read = bq4802_read_mem; | 169 | p->read = bq4802_read_mem; |
166 | p->write = bq4802_write_mem; | 170 | p->write = bq4802_write_mem; |
167 | } else { | 171 | } else { |
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h index 0abf98983e13..ccc17a2e293d 100644 --- a/drivers/rtc/rtc-core.h +++ b/drivers/rtc/rtc-core.h | |||
@@ -40,9 +40,23 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc) | |||
40 | 40 | ||
41 | #ifdef CONFIG_RTC_INTF_SYSFS | 41 | #ifdef CONFIG_RTC_INTF_SYSFS |
42 | const struct attribute_group **rtc_get_dev_attribute_groups(void); | 42 | const struct attribute_group **rtc_get_dev_attribute_groups(void); |
43 | int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp); | ||
44 | int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps); | ||
43 | #else | 45 | #else |
44 | static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) | 46 | static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) |
45 | { | 47 | { |
46 | return NULL; | 48 | return NULL; |
47 | } | 49 | } |
50 | |||
51 | static inline | ||
52 | int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp) | ||
53 | { | ||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static inline | ||
58 | int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps) | ||
59 | { | ||
60 | return 0; | ||
61 | } | ||
48 | #endif | 62 | #endif |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index efa221e8bc22..43d962a9c210 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -341,11 +341,11 @@ static long rtc_dev_ioctl(struct file *file, | |||
341 | return rtc_set_time(rtc, &tm); | 341 | return rtc_set_time(rtc, &tm); |
342 | 342 | ||
343 | case RTC_PIE_ON: | 343 | case RTC_PIE_ON: |
344 | err = rtc_irq_set_state(rtc, NULL, 1); | 344 | err = rtc_irq_set_state(rtc, 1); |
345 | break; | 345 | break; |
346 | 346 | ||
347 | case RTC_PIE_OFF: | 347 | case RTC_PIE_OFF: |
348 | err = rtc_irq_set_state(rtc, NULL, 0); | 348 | err = rtc_irq_set_state(rtc, 0); |
349 | break; | 349 | break; |
350 | 350 | ||
351 | case RTC_AIE_ON: | 351 | case RTC_AIE_ON: |
@@ -365,7 +365,7 @@ static long rtc_dev_ioctl(struct file *file, | |||
365 | return rtc_update_irq_enable(rtc, 0); | 365 | return rtc_update_irq_enable(rtc, 0); |
366 | 366 | ||
367 | case RTC_IRQP_SET: | 367 | case RTC_IRQP_SET: |
368 | err = rtc_irq_set_freq(rtc, NULL, arg); | 368 | err = rtc_irq_set_freq(rtc, arg); |
369 | break; | 369 | break; |
370 | 370 | ||
371 | case RTC_IRQP_READ: | 371 | case RTC_IRQP_READ: |
@@ -427,7 +427,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file) | |||
427 | /* Keep ioctl until all drivers are converted */ | 427 | /* Keep ioctl until all drivers are converted */ |
428 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); | 428 | rtc_dev_ioctl(file, RTC_UIE_OFF, 0); |
429 | rtc_update_irq_enable(rtc, 0); | 429 | rtc_update_irq_enable(rtc, 0); |
430 | rtc_irq_set_state(rtc, NULL, 0); | 430 | rtc_irq_set_state(rtc, 0); |
431 | 431 | ||
432 | clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); | 432 | clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); |
433 | return 0; | 433 | return 0; |
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index e9ec4160d7f6..4b2b4627daeb 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -44,6 +44,7 @@ enum ds_type { | |||
44 | ds_3231, | 44 | ds_3231, |
45 | m41t0, | 45 | m41t0, |
46 | m41t00, | 46 | m41t00, |
47 | m41t11, | ||
47 | mcp794xx, | 48 | mcp794xx, |
48 | rx_8025, | 49 | rx_8025, |
49 | rx_8130, | 50 | rx_8130, |
@@ -227,6 +228,11 @@ static const struct chip_desc chips[last_ds_type] = { | |||
227 | .irq_handler = rx8130_irq, | 228 | .irq_handler = rx8130_irq, |
228 | .rtc_ops = &rx8130_rtc_ops, | 229 | .rtc_ops = &rx8130_rtc_ops, |
229 | }, | 230 | }, |
231 | [m41t11] = { | ||
232 | /* this is battery backed SRAM */ | ||
233 | .nvram_offset = 8, | ||
234 | .nvram_size = 56, | ||
235 | }, | ||
230 | [mcp794xx] = { | 236 | [mcp794xx] = { |
231 | .alarm = 1, | 237 | .alarm = 1, |
232 | /* this is battery backed SRAM */ | 238 | /* this is battery backed SRAM */ |
@@ -249,6 +255,7 @@ static const struct i2c_device_id ds1307_id[] = { | |||
249 | { "ds3231", ds_3231 }, | 255 | { "ds3231", ds_3231 }, |
250 | { "m41t0", m41t0 }, | 256 | { "m41t0", m41t0 }, |
251 | { "m41t00", m41t00 }, | 257 | { "m41t00", m41t00 }, |
258 | { "m41t11", m41t11 }, | ||
252 | { "mcp7940x", mcp794xx }, | 259 | { "mcp7940x", mcp794xx }, |
253 | { "mcp7941x", mcp794xx }, | 260 | { "mcp7941x", mcp794xx }, |
254 | { "pt7c4338", ds_1307 }, | 261 | { "pt7c4338", ds_1307 }, |
@@ -299,13 +306,17 @@ static const struct of_device_id ds1307_of_match[] = { | |||
299 | }, | 306 | }, |
300 | { | 307 | { |
301 | .compatible = "st,m41t0", | 308 | .compatible = "st,m41t0", |
302 | .data = (void *)m41t00 | 309 | .data = (void *)m41t0 |
303 | }, | 310 | }, |
304 | { | 311 | { |
305 | .compatible = "st,m41t00", | 312 | .compatible = "st,m41t00", |
306 | .data = (void *)m41t00 | 313 | .data = (void *)m41t00 |
307 | }, | 314 | }, |
308 | { | 315 | { |
316 | .compatible = "st,m41t11", | ||
317 | .data = (void *)m41t11 | ||
318 | }, | ||
319 | { | ||
309 | .compatible = "microchip,mcp7940x", | 320 | .compatible = "microchip,mcp7940x", |
310 | .data = (void *)mcp794xx | 321 | .data = (void *)mcp794xx |
311 | }, | 322 | }, |
@@ -347,6 +358,7 @@ static const struct acpi_device_id ds1307_acpi_ids[] = { | |||
347 | { .id = "DS3231", .driver_data = ds_3231 }, | 358 | { .id = "DS3231", .driver_data = ds_3231 }, |
348 | { .id = "M41T0", .driver_data = m41t0 }, | 359 | { .id = "M41T0", .driver_data = m41t0 }, |
349 | { .id = "M41T00", .driver_data = m41t00 }, | 360 | { .id = "M41T00", .driver_data = m41t00 }, |
361 | { .id = "M41T11", .driver_data = m41t11 }, | ||
350 | { .id = "MCP7940X", .driver_data = mcp794xx }, | 362 | { .id = "MCP7940X", .driver_data = mcp794xx }, |
351 | { .id = "MCP7941X", .driver_data = mcp794xx }, | 363 | { .id = "MCP7941X", .driver_data = mcp794xx }, |
352 | { .id = "PT7C4338", .driver_data = ds_1307 }, | 364 | { .id = "PT7C4338", .driver_data = ds_1307 }, |
@@ -1030,7 +1042,7 @@ static u8 ds1307_trickle_init(struct ds1307 *ds1307, | |||
1030 | 1042 | ||
1031 | /*----------------------------------------------------------------------*/ | 1043 | /*----------------------------------------------------------------------*/ |
1032 | 1044 | ||
1033 | #ifdef CONFIG_RTC_DRV_DS1307_HWMON | 1045 | #if IS_REACHABLE(CONFIG_HWMON) |
1034 | 1046 | ||
1035 | /* | 1047 | /* |
1036 | * Temperature sensor support for ds3231 devices. | 1048 | * Temperature sensor support for ds3231 devices. |
@@ -1576,6 +1588,7 @@ read_rtc: | |||
1576 | case ds_1307: | 1588 | case ds_1307: |
1577 | case m41t0: | 1589 | case m41t0: |
1578 | case m41t00: | 1590 | case m41t00: |
1591 | case m41t11: | ||
1579 | /* clock halted? turn it on, so clock can tick. */ | 1592 | /* clock halted? turn it on, so clock can tick. */ |
1580 | if (tmp & DS1307_BIT_CH) { | 1593 | if (tmp & DS1307_BIT_CH) { |
1581 | regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); | 1594 | regmap_write(ds1307->regmap, DS1307_REG_SECS, 0); |
@@ -1641,6 +1654,7 @@ read_rtc: | |||
1641 | case ds_1340: | 1654 | case ds_1340: |
1642 | case m41t0: | 1655 | case m41t0: |
1643 | case m41t00: | 1656 | case m41t00: |
1657 | case m41t11: | ||
1644 | /* | 1658 | /* |
1645 | * NOTE: ignores century bits; fix before deploying | 1659 | * NOTE: ignores century bits; fix before deploying |
1646 | * systems that will run through year 2100. | 1660 | * systems that will run through year 2100. |
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c index 5c0db6c8134c..6f39f683a98c 100644 --- a/drivers/rtc/rtc-ds1685.c +++ b/drivers/rtc/rtc-ds1685.c | |||
@@ -1188,552 +1188,6 @@ ds1685_rtc_sysfs_misc_grp = { | |||
1188 | .attrs = ds1685_rtc_sysfs_misc_attrs, | 1188 | .attrs = ds1685_rtc_sysfs_misc_attrs, |
1189 | }; | 1189 | }; |
1190 | 1190 | ||
1191 | #ifdef CONFIG_RTC_DS1685_SYSFS_REGS | ||
1192 | /** | ||
1193 | * struct ds1685_rtc_ctrl_regs. | ||
1194 | * @name: char pointer for the bit name. | ||
1195 | * @reg: control register the bit is in. | ||
1196 | * @bit: the bit's offset in the register. | ||
1197 | */ | ||
1198 | struct ds1685_rtc_ctrl_regs { | ||
1199 | const char *name; | ||
1200 | const u8 reg; | ||
1201 | const u8 bit; | ||
1202 | }; | ||
1203 | |||
1204 | /* | ||
1205 | * Ctrl register bit lookup table. | ||
1206 | */ | ||
1207 | static const struct ds1685_rtc_ctrl_regs | ||
1208 | ds1685_ctrl_regs_table[] = { | ||
1209 | { "uip", RTC_CTRL_A, RTC_CTRL_A_UIP }, | ||
1210 | { "dv2", RTC_CTRL_A, RTC_CTRL_A_DV2 }, | ||
1211 | { "dv1", RTC_CTRL_A, RTC_CTRL_A_DV1 }, | ||
1212 | { "dv0", RTC_CTRL_A, RTC_CTRL_A_DV0 }, | ||
1213 | { "rs3", RTC_CTRL_A, RTC_CTRL_A_RS3 }, | ||
1214 | { "rs2", RTC_CTRL_A, RTC_CTRL_A_RS2 }, | ||
1215 | { "rs1", RTC_CTRL_A, RTC_CTRL_A_RS1 }, | ||
1216 | { "rs0", RTC_CTRL_A, RTC_CTRL_A_RS0 }, | ||
1217 | { "set", RTC_CTRL_B, RTC_CTRL_B_SET }, | ||
1218 | { "pie", RTC_CTRL_B, RTC_CTRL_B_PIE }, | ||
1219 | { "aie", RTC_CTRL_B, RTC_CTRL_B_AIE }, | ||
1220 | { "uie", RTC_CTRL_B, RTC_CTRL_B_UIE }, | ||
1221 | { "sqwe", RTC_CTRL_B, RTC_CTRL_B_SQWE }, | ||
1222 | { "dm", RTC_CTRL_B, RTC_CTRL_B_DM }, | ||
1223 | { "2412", RTC_CTRL_B, RTC_CTRL_B_2412 }, | ||
1224 | { "dse", RTC_CTRL_B, RTC_CTRL_B_DSE }, | ||
1225 | { "irqf", RTC_CTRL_C, RTC_CTRL_C_IRQF }, | ||
1226 | { "pf", RTC_CTRL_C, RTC_CTRL_C_PF }, | ||
1227 | { "af", RTC_CTRL_C, RTC_CTRL_C_AF }, | ||
1228 | { "uf", RTC_CTRL_C, RTC_CTRL_C_UF }, | ||
1229 | { "vrt", RTC_CTRL_D, RTC_CTRL_D_VRT }, | ||
1230 | { "vrt2", RTC_EXT_CTRL_4A, RTC_CTRL_4A_VRT2 }, | ||
1231 | { "incr", RTC_EXT_CTRL_4A, RTC_CTRL_4A_INCR }, | ||
1232 | { "pab", RTC_EXT_CTRL_4A, RTC_CTRL_4A_PAB }, | ||
1233 | { "rf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_RF }, | ||
1234 | { "wf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_WF }, | ||
1235 | { "kf", RTC_EXT_CTRL_4A, RTC_CTRL_4A_KF }, | ||
1236 | #if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689) | ||
1237 | { "bme", RTC_EXT_CTRL_4A, RTC_CTRL_4A_BME }, | ||
1238 | #endif | ||
1239 | { "abe", RTC_EXT_CTRL_4B, RTC_CTRL_4B_ABE }, | ||
1240 | { "e32k", RTC_EXT_CTRL_4B, RTC_CTRL_4B_E32K }, | ||
1241 | { "cs", RTC_EXT_CTRL_4B, RTC_CTRL_4B_CS }, | ||
1242 | { "rce", RTC_EXT_CTRL_4B, RTC_CTRL_4B_RCE }, | ||
1243 | { "prs", RTC_EXT_CTRL_4B, RTC_CTRL_4B_PRS }, | ||
1244 | { "rie", RTC_EXT_CTRL_4B, RTC_CTRL_4B_RIE }, | ||
1245 | { "wie", RTC_EXT_CTRL_4B, RTC_CTRL_4B_WIE }, | ||
1246 | { "kse", RTC_EXT_CTRL_4B, RTC_CTRL_4B_KSE }, | ||
1247 | { NULL, 0, 0 }, | ||
1248 | }; | ||
1249 | |||
1250 | /** | ||
1251 | * ds1685_rtc_sysfs_ctrl_regs_lookup - ctrl register bit lookup function. | ||
1252 | * @name: ctrl register bit to look up in ds1685_ctrl_regs_table. | ||
1253 | */ | ||
1254 | static const struct ds1685_rtc_ctrl_regs* | ||
1255 | ds1685_rtc_sysfs_ctrl_regs_lookup(const char *name) | ||
1256 | { | ||
1257 | const struct ds1685_rtc_ctrl_regs *p = ds1685_ctrl_regs_table; | ||
1258 | |||
1259 | for (; p->name != NULL; ++p) | ||
1260 | if (strcmp(p->name, name) == 0) | ||
1261 | return p; | ||
1262 | |||
1263 | return NULL; | ||
1264 | } | ||
1265 | |||
1266 | /** | ||
1267 | * ds1685_rtc_sysfs_ctrl_regs_show - reads a ctrl register bit via sysfs. | ||
1268 | * @dev: pointer to device structure. | ||
1269 | * @attr: pointer to device_attribute structure. | ||
1270 | * @buf: pointer to char array to hold the output. | ||
1271 | */ | ||
1272 | static ssize_t | ||
1273 | ds1685_rtc_sysfs_ctrl_regs_show(struct device *dev, | ||
1274 | struct device_attribute *attr, char *buf) | ||
1275 | { | ||
1276 | u8 tmp; | ||
1277 | struct ds1685_priv *rtc = dev_get_drvdata(dev); | ||
1278 | const struct ds1685_rtc_ctrl_regs *reg_info = | ||
1279 | ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name); | ||
1280 | |||
1281 | /* Make sure we actually matched something. */ | ||
1282 | if (!reg_info) | ||
1283 | return -EINVAL; | ||
1284 | |||
1285 | /* No spinlock during a read -- mutex is already held. */ | ||
1286 | ds1685_rtc_switch_to_bank1(rtc); | ||
1287 | tmp = rtc->read(rtc, reg_info->reg) & reg_info->bit; | ||
1288 | ds1685_rtc_switch_to_bank0(rtc); | ||
1289 | |||
1290 | return sprintf(buf, "%d\n", (tmp ? 1 : 0)); | ||
1291 | } | ||
1292 | |||
1293 | /** | ||
1294 | * ds1685_rtc_sysfs_ctrl_regs_store - writes a ctrl register bit via sysfs. | ||
1295 | * @dev: pointer to device structure. | ||
1296 | * @attr: pointer to device_attribute structure. | ||
1297 | * @buf: pointer to char array to hold the output. | ||
1298 | * @count: number of bytes written. | ||
1299 | */ | ||
1300 | static ssize_t | ||
1301 | ds1685_rtc_sysfs_ctrl_regs_store(struct device *dev, | ||
1302 | struct device_attribute *attr, | ||
1303 | const char *buf, size_t count) | ||
1304 | { | ||
1305 | struct ds1685_priv *rtc = dev_get_drvdata(dev); | ||
1306 | u8 reg = 0, bit = 0, tmp; | ||
1307 | unsigned long flags; | ||
1308 | long int val = 0; | ||
1309 | const struct ds1685_rtc_ctrl_regs *reg_info = | ||
1310 | ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name); | ||
1311 | |||
1312 | /* We only accept numbers. */ | ||
1313 | if (kstrtol(buf, 10, &val) < 0) | ||
1314 | return -EINVAL; | ||
1315 | |||
1316 | /* bits are binary, 0 or 1 only. */ | ||
1317 | if ((val != 0) && (val != 1)) | ||
1318 | return -ERANGE; | ||
1319 | |||
1320 | /* Make sure we actually matched something. */ | ||
1321 | if (!reg_info) | ||
1322 | return -EINVAL; | ||
1323 | |||
1324 | reg = reg_info->reg; | ||
1325 | bit = reg_info->bit; | ||
1326 | |||
1327 | /* Safe to spinlock during a write. */ | ||
1328 | ds1685_rtc_begin_ctrl_access(rtc, &flags); | ||
1329 | tmp = rtc->read(rtc, reg); | ||
1330 | rtc->write(rtc, reg, (val ? (tmp | bit) : (tmp & ~(bit)))); | ||
1331 | ds1685_rtc_end_ctrl_access(rtc, flags); | ||
1332 | |||
1333 | return count; | ||
1334 | } | ||
1335 | |||
1336 | /** | ||
1337 | * DS1685_RTC_SYSFS_CTRL_REG_RO - device_attribute for read-only register bit. | ||
1338 | * @bit: bit to read. | ||
1339 | */ | ||
1340 | #define DS1685_RTC_SYSFS_CTRL_REG_RO(bit) \ | ||
1341 | static DEVICE_ATTR(bit, S_IRUGO, \ | ||
1342 | ds1685_rtc_sysfs_ctrl_regs_show, NULL) | ||
1343 | |||
1344 | /** | ||
1345 | * DS1685_RTC_SYSFS_CTRL_REG_RW - device_attribute for read-write register bit. | ||
1346 | * @bit: bit to read or write. | ||
1347 | */ | ||
1348 | #define DS1685_RTC_SYSFS_CTRL_REG_RW(bit) \ | ||
1349 | static DEVICE_ATTR(bit, S_IRUGO | S_IWUSR, \ | ||
1350 | ds1685_rtc_sysfs_ctrl_regs_show, \ | ||
1351 | ds1685_rtc_sysfs_ctrl_regs_store) | ||
1352 | |||
1353 | /* | ||
1354 | * Control Register A bits. | ||
1355 | */ | ||
1356 | DS1685_RTC_SYSFS_CTRL_REG_RO(uip); | ||
1357 | DS1685_RTC_SYSFS_CTRL_REG_RW(dv2); | ||
1358 | DS1685_RTC_SYSFS_CTRL_REG_RW(dv1); | ||
1359 | DS1685_RTC_SYSFS_CTRL_REG_RO(dv0); | ||
1360 | DS1685_RTC_SYSFS_CTRL_REG_RW(rs3); | ||
1361 | DS1685_RTC_SYSFS_CTRL_REG_RW(rs2); | ||
1362 | DS1685_RTC_SYSFS_CTRL_REG_RW(rs1); | ||
1363 | DS1685_RTC_SYSFS_CTRL_REG_RW(rs0); | ||
1364 | |||
1365 | static struct attribute* | ||
1366 | ds1685_rtc_sysfs_ctrla_attrs[] = { | ||
1367 | &dev_attr_uip.attr, | ||
1368 | &dev_attr_dv2.attr, | ||
1369 | &dev_attr_dv1.attr, | ||
1370 | &dev_attr_dv0.attr, | ||
1371 | &dev_attr_rs3.attr, | ||
1372 | &dev_attr_rs2.attr, | ||
1373 | &dev_attr_rs1.attr, | ||
1374 | &dev_attr_rs0.attr, | ||
1375 | NULL, | ||
1376 | }; | ||
1377 | |||
1378 | static const struct attribute_group | ||
1379 | ds1685_rtc_sysfs_ctrla_grp = { | ||
1380 | .name = "ctrla", | ||
1381 | .attrs = ds1685_rtc_sysfs_ctrla_attrs, | ||
1382 | }; | ||
1383 | |||
1384 | |||
1385 | /* | ||
1386 | * Control Register B bits. | ||
1387 | */ | ||
1388 | DS1685_RTC_SYSFS_CTRL_REG_RO(set); | ||
1389 | DS1685_RTC_SYSFS_CTRL_REG_RW(pie); | ||
1390 | DS1685_RTC_SYSFS_CTRL_REG_RW(aie); | ||
1391 | DS1685_RTC_SYSFS_CTRL_REG_RW(uie); | ||
1392 | DS1685_RTC_SYSFS_CTRL_REG_RW(sqwe); | ||
1393 | DS1685_RTC_SYSFS_CTRL_REG_RO(dm); | ||
1394 | DS1685_RTC_SYSFS_CTRL_REG_RO(2412); | ||
1395 | DS1685_RTC_SYSFS_CTRL_REG_RO(dse); | ||
1396 | |||
1397 | static struct attribute* | ||
1398 | ds1685_rtc_sysfs_ctrlb_attrs[] = { | ||
1399 | &dev_attr_set.attr, | ||
1400 | &dev_attr_pie.attr, | ||
1401 | &dev_attr_aie.attr, | ||
1402 | &dev_attr_uie.attr, | ||
1403 | &dev_attr_sqwe.attr, | ||
1404 | &dev_attr_dm.attr, | ||
1405 | &dev_attr_2412.attr, | ||
1406 | &dev_attr_dse.attr, | ||
1407 | NULL, | ||
1408 | }; | ||
1409 | |||
1410 | static const struct attribute_group | ||
1411 | ds1685_rtc_sysfs_ctrlb_grp = { | ||
1412 | .name = "ctrlb", | ||
1413 | .attrs = ds1685_rtc_sysfs_ctrlb_attrs, | ||
1414 | }; | ||
1415 | |||
1416 | /* | ||
1417 | * Control Register C bits. | ||
1418 | * | ||
1419 | * Reading Control C clears these bits! Reading them individually can | ||
1420 | * possibly cause an interrupt to be missed. Use the /proc interface | ||
1421 | * to see all the bits in this register simultaneously. | ||
1422 | */ | ||
1423 | DS1685_RTC_SYSFS_CTRL_REG_RO(irqf); | ||
1424 | DS1685_RTC_SYSFS_CTRL_REG_RO(pf); | ||
1425 | DS1685_RTC_SYSFS_CTRL_REG_RO(af); | ||
1426 | DS1685_RTC_SYSFS_CTRL_REG_RO(uf); | ||
1427 | |||
1428 | static struct attribute* | ||
1429 | ds1685_rtc_sysfs_ctrlc_attrs[] = { | ||
1430 | &dev_attr_irqf.attr, | ||
1431 | &dev_attr_pf.attr, | ||
1432 | &dev_attr_af.attr, | ||
1433 | &dev_attr_uf.attr, | ||
1434 | NULL, | ||
1435 | }; | ||
1436 | |||
1437 | static const struct attribute_group | ||
1438 | ds1685_rtc_sysfs_ctrlc_grp = { | ||
1439 | .name = "ctrlc", | ||
1440 | .attrs = ds1685_rtc_sysfs_ctrlc_attrs, | ||
1441 | }; | ||
1442 | |||
1443 | /* | ||
1444 | * Control Register D bits. | ||
1445 | */ | ||
1446 | DS1685_RTC_SYSFS_CTRL_REG_RO(vrt); | ||
1447 | |||
1448 | static struct attribute* | ||
1449 | ds1685_rtc_sysfs_ctrld_attrs[] = { | ||
1450 | &dev_attr_vrt.attr, | ||
1451 | NULL, | ||
1452 | }; | ||
1453 | |||
1454 | static const struct attribute_group | ||
1455 | ds1685_rtc_sysfs_ctrld_grp = { | ||
1456 | .name = "ctrld", | ||
1457 | .attrs = ds1685_rtc_sysfs_ctrld_attrs, | ||
1458 | }; | ||
1459 | |||
1460 | /* | ||
1461 | * Control Register 4A bits. | ||
1462 | */ | ||
1463 | DS1685_RTC_SYSFS_CTRL_REG_RO(vrt2); | ||
1464 | DS1685_RTC_SYSFS_CTRL_REG_RO(incr); | ||
1465 | DS1685_RTC_SYSFS_CTRL_REG_RW(pab); | ||
1466 | DS1685_RTC_SYSFS_CTRL_REG_RW(rf); | ||
1467 | DS1685_RTC_SYSFS_CTRL_REG_RW(wf); | ||
1468 | DS1685_RTC_SYSFS_CTRL_REG_RW(kf); | ||
1469 | #if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689) | ||
1470 | DS1685_RTC_SYSFS_CTRL_REG_RO(bme); | ||
1471 | #endif | ||
1472 | |||
1473 | static struct attribute* | ||
1474 | ds1685_rtc_sysfs_ctrl4a_attrs[] = { | ||
1475 | &dev_attr_vrt2.attr, | ||
1476 | &dev_attr_incr.attr, | ||
1477 | &dev_attr_pab.attr, | ||
1478 | &dev_attr_rf.attr, | ||
1479 | &dev_attr_wf.attr, | ||
1480 | &dev_attr_kf.attr, | ||
1481 | #if !defined(CONFIG_RTC_DRV_DS1685) && !defined(CONFIG_RTC_DRV_DS1689) | ||
1482 | &dev_attr_bme.attr, | ||
1483 | #endif | ||
1484 | NULL, | ||
1485 | }; | ||
1486 | |||
1487 | static const struct attribute_group | ||
1488 | ds1685_rtc_sysfs_ctrl4a_grp = { | ||
1489 | .name = "ctrl4a", | ||
1490 | .attrs = ds1685_rtc_sysfs_ctrl4a_attrs, | ||
1491 | }; | ||
1492 | |||
1493 | /* | ||
1494 | * Control Register 4B bits. | ||
1495 | */ | ||
1496 | DS1685_RTC_SYSFS_CTRL_REG_RW(abe); | ||
1497 | DS1685_RTC_SYSFS_CTRL_REG_RW(e32k); | ||
1498 | DS1685_RTC_SYSFS_CTRL_REG_RO(cs); | ||
1499 | DS1685_RTC_SYSFS_CTRL_REG_RW(rce); | ||
1500 | DS1685_RTC_SYSFS_CTRL_REG_RW(prs); | ||
1501 | DS1685_RTC_SYSFS_CTRL_REG_RW(rie); | ||
1502 | DS1685_RTC_SYSFS_CTRL_REG_RW(wie); | ||
1503 | DS1685_RTC_SYSFS_CTRL_REG_RW(kse); | ||
1504 | |||
1505 | static struct attribute* | ||
1506 | ds1685_rtc_sysfs_ctrl4b_attrs[] = { | ||
1507 | &dev_attr_abe.attr, | ||
1508 | &dev_attr_e32k.attr, | ||
1509 | &dev_attr_cs.attr, | ||
1510 | &dev_attr_rce.attr, | ||
1511 | &dev_attr_prs.attr, | ||
1512 | &dev_attr_rie.attr, | ||
1513 | &dev_attr_wie.attr, | ||
1514 | &dev_attr_kse.attr, | ||
1515 | NULL, | ||
1516 | }; | ||
1517 | |||
1518 | static const struct attribute_group | ||
1519 | ds1685_rtc_sysfs_ctrl4b_grp = { | ||
1520 | .name = "ctrl4b", | ||
1521 | .attrs = ds1685_rtc_sysfs_ctrl4b_attrs, | ||
1522 | }; | ||
1523 | |||
1524 | |||
1525 | /** | ||
1526 | * struct ds1685_rtc_ctrl_regs. | ||
1527 | * @name: char pointer for the bit name. | ||
1528 | * @reg: control register the bit is in. | ||
1529 | * @bit: the bit's offset in the register. | ||
1530 | */ | ||
1531 | struct ds1685_rtc_time_regs { | ||
1532 | const char *name; | ||
1533 | const u8 reg; | ||
1534 | const u8 mask; | ||
1535 | const u8 min; | ||
1536 | const u8 max; | ||
1537 | }; | ||
1538 | |||
1539 | /* | ||
1540 | * Time/Date register lookup tables. | ||
1541 | */ | ||
1542 | static const struct ds1685_rtc_time_regs | ||
1543 | ds1685_time_regs_bcd_table[] = { | ||
1544 | { "seconds", RTC_SECS, RTC_SECS_BCD_MASK, 0, 59 }, | ||
1545 | { "minutes", RTC_MINS, RTC_MINS_BCD_MASK, 0, 59 }, | ||
1546 | { "hours", RTC_HRS, RTC_HRS_24_BCD_MASK, 0, 23 }, | ||
1547 | { "wday", RTC_WDAY, RTC_WDAY_MASK, 1, 7 }, | ||
1548 | { "mday", RTC_MDAY, RTC_MDAY_BCD_MASK, 1, 31 }, | ||
1549 | { "month", RTC_MONTH, RTC_MONTH_BCD_MASK, 1, 12 }, | ||
1550 | { "year", RTC_YEAR, RTC_YEAR_BCD_MASK, 0, 99 }, | ||
1551 | { "century", RTC_CENTURY, RTC_CENTURY_MASK, 0, 99 }, | ||
1552 | { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BCD_MASK, 0, 59 }, | ||
1553 | { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BCD_MASK, 0, 59 }, | ||
1554 | { "alarm_hours", RTC_HRS_ALARM, RTC_HRS_24_BCD_MASK, 0, 23 }, | ||
1555 | { "alarm_mday", RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 1, 31 }, | ||
1556 | { NULL, 0, 0, 0, 0 }, | ||
1557 | }; | ||
1558 | |||
1559 | static const struct ds1685_rtc_time_regs | ||
1560 | ds1685_time_regs_bin_table[] = { | ||
1561 | { "seconds", RTC_SECS, RTC_SECS_BIN_MASK, 0x00, 0x3b }, | ||
1562 | { "minutes", RTC_MINS, RTC_MINS_BIN_MASK, 0x00, 0x3b }, | ||
1563 | { "hours", RTC_HRS, RTC_HRS_24_BIN_MASK, 0x00, 0x17 }, | ||
1564 | { "wday", RTC_WDAY, RTC_WDAY_MASK, 0x01, 0x07 }, | ||
1565 | { "mday", RTC_MDAY, RTC_MDAY_BIN_MASK, 0x01, 0x1f }, | ||
1566 | { "month", RTC_MONTH, RTC_MONTH_BIN_MASK, 0x01, 0x0c }, | ||
1567 | { "year", RTC_YEAR, RTC_YEAR_BIN_MASK, 0x00, 0x63 }, | ||
1568 | { "century", RTC_CENTURY, RTC_CENTURY_MASK, 0x00, 0x63 }, | ||
1569 | { "alarm_seconds", RTC_SECS_ALARM, RTC_SECS_BIN_MASK, 0x00, 0x3b }, | ||
1570 | { "alarm_minutes", RTC_MINS_ALARM, RTC_MINS_BIN_MASK, 0x00, 0x3b }, | ||
1571 | { "alarm_hours", RTC_HRS_ALARM, RTC_HRS_24_BIN_MASK, 0x00, 0x17 }, | ||
1572 | { "alarm_mday", RTC_MDAY_ALARM, RTC_MDAY_ALARM_MASK, 0x01, 0x1f }, | ||
1573 | { NULL, 0, 0, 0x00, 0x00 }, | ||
1574 | }; | ||
1575 | |||
1576 | /** | ||
1577 | * ds1685_rtc_sysfs_time_regs_bcd_lookup - time/date reg bit lookup function. | ||
1578 | * @name: register bit to look up in ds1685_time_regs_bcd_table. | ||
1579 | */ | ||
1580 | static const struct ds1685_rtc_time_regs* | ||
1581 | ds1685_rtc_sysfs_time_regs_lookup(const char *name, bool bcd_mode) | ||
1582 | { | ||
1583 | const struct ds1685_rtc_time_regs *p; | ||
1584 | |||
1585 | if (bcd_mode) | ||
1586 | p = ds1685_time_regs_bcd_table; | ||
1587 | else | ||
1588 | p = ds1685_time_regs_bin_table; | ||
1589 | |||
1590 | for (; p->name != NULL; ++p) | ||
1591 | if (strcmp(p->name, name) == 0) | ||
1592 | return p; | ||
1593 | |||
1594 | return NULL; | ||
1595 | } | ||
1596 | |||
1597 | /** | ||
1598 | * ds1685_rtc_sysfs_time_regs_show - reads a time/date register via sysfs. | ||
1599 | * @dev: pointer to device structure. | ||
1600 | * @attr: pointer to device_attribute structure. | ||
1601 | * @buf: pointer to char array to hold the output. | ||
1602 | */ | ||
1603 | static ssize_t | ||
1604 | ds1685_rtc_sysfs_time_regs_show(struct device *dev, | ||
1605 | struct device_attribute *attr, char *buf) | ||
1606 | { | ||
1607 | u8 tmp; | ||
1608 | struct ds1685_priv *rtc = dev_get_drvdata(dev); | ||
1609 | const struct ds1685_rtc_time_regs *bcd_reg_info = | ||
1610 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true); | ||
1611 | const struct ds1685_rtc_time_regs *bin_reg_info = | ||
1612 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false); | ||
1613 | |||
1614 | /* Make sure we actually matched something. */ | ||
1615 | if (!bcd_reg_info || !bin_reg_info) | ||
1616 | return -EINVAL; | ||
1617 | |||
1618 | /* bcd_reg_info->reg == bin_reg_info->reg. */ | ||
1619 | ds1685_rtc_begin_data_access(rtc); | ||
1620 | tmp = rtc->read(rtc, bcd_reg_info->reg); | ||
1621 | ds1685_rtc_end_data_access(rtc); | ||
1622 | |||
1623 | tmp = ds1685_rtc_bcd2bin(rtc, tmp, bcd_reg_info->mask, | ||
1624 | bin_reg_info->mask); | ||
1625 | |||
1626 | return sprintf(buf, "%d\n", tmp); | ||
1627 | } | ||
1628 | |||
1629 | /** | ||
1630 | * ds1685_rtc_sysfs_time_regs_store - writes a time/date register via sysfs. | ||
1631 | * @dev: pointer to device structure. | ||
1632 | * @attr: pointer to device_attribute structure. | ||
1633 | * @buf: pointer to char array to hold the output. | ||
1634 | * @count: number of bytes written. | ||
1635 | */ | ||
1636 | static ssize_t | ||
1637 | ds1685_rtc_sysfs_time_regs_store(struct device *dev, | ||
1638 | struct device_attribute *attr, | ||
1639 | const char *buf, size_t count) | ||
1640 | { | ||
1641 | long int val = 0; | ||
1642 | struct ds1685_priv *rtc = dev_get_drvdata(dev); | ||
1643 | const struct ds1685_rtc_time_regs *bcd_reg_info = | ||
1644 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, true); | ||
1645 | const struct ds1685_rtc_time_regs *bin_reg_info = | ||
1646 | ds1685_rtc_sysfs_time_regs_lookup(attr->attr.name, false); | ||
1647 | |||
1648 | /* We only accept numbers. */ | ||
1649 | if (kstrtol(buf, 10, &val) < 0) | ||
1650 | return -EINVAL; | ||
1651 | |||
1652 | /* Make sure we actually matched something. */ | ||
1653 | if (!bcd_reg_info || !bin_reg_info) | ||
1654 | return -EINVAL; | ||
1655 | |||
1656 | /* Check for a valid range. */ | ||
1657 | if (rtc->bcd_mode) { | ||
1658 | if ((val < bcd_reg_info->min) || (val > bcd_reg_info->max)) | ||
1659 | return -ERANGE; | ||
1660 | } else { | ||
1661 | if ((val < bin_reg_info->min) || (val > bin_reg_info->max)) | ||
1662 | return -ERANGE; | ||
1663 | } | ||
1664 | |||
1665 | val = ds1685_rtc_bin2bcd(rtc, val, bin_reg_info->mask, | ||
1666 | bcd_reg_info->mask); | ||
1667 | |||
1668 | /* bcd_reg_info->reg == bin_reg_info->reg. */ | ||
1669 | ds1685_rtc_begin_data_access(rtc); | ||
1670 | rtc->write(rtc, bcd_reg_info->reg, val); | ||
1671 | ds1685_rtc_end_data_access(rtc); | ||
1672 | |||
1673 | return count; | ||
1674 | } | ||
1675 | |||
1676 | /** | ||
1677 | * DS1685_RTC_SYSFS_REG_RW - device_attribute for a read-write time register. | ||
1678 | * @reg: time/date register to read or write. | ||
1679 | */ | ||
1680 | #define DS1685_RTC_SYSFS_TIME_REG_RW(reg) \ | ||
1681 | static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, \ | ||
1682 | ds1685_rtc_sysfs_time_regs_show, \ | ||
1683 | ds1685_rtc_sysfs_time_regs_store) | ||
1684 | |||
1685 | /* | ||
1686 | * Time/Date Register bits. | ||
1687 | */ | ||
1688 | DS1685_RTC_SYSFS_TIME_REG_RW(seconds); | ||
1689 | DS1685_RTC_SYSFS_TIME_REG_RW(minutes); | ||
1690 | DS1685_RTC_SYSFS_TIME_REG_RW(hours); | ||
1691 | DS1685_RTC_SYSFS_TIME_REG_RW(wday); | ||
1692 | DS1685_RTC_SYSFS_TIME_REG_RW(mday); | ||
1693 | DS1685_RTC_SYSFS_TIME_REG_RW(month); | ||
1694 | DS1685_RTC_SYSFS_TIME_REG_RW(year); | ||
1695 | DS1685_RTC_SYSFS_TIME_REG_RW(century); | ||
1696 | DS1685_RTC_SYSFS_TIME_REG_RW(alarm_seconds); | ||
1697 | DS1685_RTC_SYSFS_TIME_REG_RW(alarm_minutes); | ||
1698 | DS1685_RTC_SYSFS_TIME_REG_RW(alarm_hours); | ||
1699 | DS1685_RTC_SYSFS_TIME_REG_RW(alarm_mday); | ||
1700 | |||
1701 | static struct attribute* | ||
1702 | ds1685_rtc_sysfs_time_attrs[] = { | ||
1703 | &dev_attr_seconds.attr, | ||
1704 | &dev_attr_minutes.attr, | ||
1705 | &dev_attr_hours.attr, | ||
1706 | &dev_attr_wday.attr, | ||
1707 | &dev_attr_mday.attr, | ||
1708 | &dev_attr_month.attr, | ||
1709 | &dev_attr_year.attr, | ||
1710 | &dev_attr_century.attr, | ||
1711 | NULL, | ||
1712 | }; | ||
1713 | |||
1714 | static const struct attribute_group | ||
1715 | ds1685_rtc_sysfs_time_grp = { | ||
1716 | .name = "datetime", | ||
1717 | .attrs = ds1685_rtc_sysfs_time_attrs, | ||
1718 | }; | ||
1719 | |||
1720 | static struct attribute* | ||
1721 | ds1685_rtc_sysfs_alarm_attrs[] = { | ||
1722 | &dev_attr_alarm_seconds.attr, | ||
1723 | &dev_attr_alarm_minutes.attr, | ||
1724 | &dev_attr_alarm_hours.attr, | ||
1725 | &dev_attr_alarm_mday.attr, | ||
1726 | NULL, | ||
1727 | }; | ||
1728 | |||
1729 | static const struct attribute_group | ||
1730 | ds1685_rtc_sysfs_alarm_grp = { | ||
1731 | .name = "alarm", | ||
1732 | .attrs = ds1685_rtc_sysfs_alarm_attrs, | ||
1733 | }; | ||
1734 | #endif /* CONFIG_RTC_DS1685_SYSFS_REGS */ | ||
1735 | |||
1736 | |||
1737 | /** | 1191 | /** |
1738 | * ds1685_rtc_sysfs_register - register sysfs files. | 1192 | * ds1685_rtc_sysfs_register - register sysfs files. |
1739 | * @dev: pointer to device structure. | 1193 | * @dev: pointer to device structure. |
@@ -1752,39 +1206,6 @@ ds1685_rtc_sysfs_register(struct device *dev) | |||
1752 | if (ret) | 1206 | if (ret) |
1753 | return ret; | 1207 | return ret; |
1754 | 1208 | ||
1755 | #ifdef CONFIG_RTC_DS1685_SYSFS_REGS | ||
1756 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp); | ||
1757 | if (ret) | ||
1758 | return ret; | ||
1759 | |||
1760 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp); | ||
1761 | if (ret) | ||
1762 | return ret; | ||
1763 | |||
1764 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp); | ||
1765 | if (ret) | ||
1766 | return ret; | ||
1767 | |||
1768 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp); | ||
1769 | if (ret) | ||
1770 | return ret; | ||
1771 | |||
1772 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp); | ||
1773 | if (ret) | ||
1774 | return ret; | ||
1775 | |||
1776 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp); | ||
1777 | if (ret) | ||
1778 | return ret; | ||
1779 | |||
1780 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp); | ||
1781 | if (ret) | ||
1782 | return ret; | ||
1783 | |||
1784 | ret = sysfs_create_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp); | ||
1785 | if (ret) | ||
1786 | return ret; | ||
1787 | #endif | ||
1788 | return 0; | 1209 | return 0; |
1789 | } | 1210 | } |
1790 | 1211 | ||
@@ -1798,17 +1219,6 @@ ds1685_rtc_sysfs_unregister(struct device *dev) | |||
1798 | sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr); | 1219 | sysfs_remove_bin_file(&dev->kobj, &ds1685_rtc_sysfs_nvram_attr); |
1799 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp); | 1220 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_misc_grp); |
1800 | 1221 | ||
1801 | #ifdef CONFIG_RTC_DS1685_SYSFS_REGS | ||
1802 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrla_grp); | ||
1803 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlb_grp); | ||
1804 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrlc_grp); | ||
1805 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrld_grp); | ||
1806 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4a_grp); | ||
1807 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_ctrl4b_grp); | ||
1808 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_time_grp); | ||
1809 | sysfs_remove_group(&dev->kobj, &ds1685_rtc_sysfs_alarm_grp); | ||
1810 | #endif | ||
1811 | |||
1812 | return 0; | 1222 | return 0; |
1813 | } | 1223 | } |
1814 | #endif /* CONFIG_SYSFS */ | 1224 | #endif /* CONFIG_SYSFS */ |
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c index 1a2c38cc0178..ea18a8f4bce0 100644 --- a/drivers/rtc/rtc-isl1208.c +++ b/drivers/rtc/rtc-isl1208.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/bcd.h> | 15 | #include <linux/bcd.h> |
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include "rtc-core.h" | ||
18 | #include <linux/of_irq.h> | ||
17 | 19 | ||
18 | /* Register map */ | 20 | /* Register map */ |
19 | /* rtc section */ | 21 | /* rtc section */ |
@@ -33,13 +35,16 @@ | |||
33 | #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ | 35 | #define ISL1208_REG_SR_ARST (1<<7) /* auto reset */ |
34 | #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ | 36 | #define ISL1208_REG_SR_XTOSCB (1<<6) /* crystal oscillator */ |
35 | #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ | 37 | #define ISL1208_REG_SR_WRTC (1<<4) /* write rtc */ |
38 | #define ISL1208_REG_SR_EVT (1<<3) /* event */ | ||
36 | #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ | 39 | #define ISL1208_REG_SR_ALM (1<<2) /* alarm */ |
37 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ | 40 | #define ISL1208_REG_SR_BAT (1<<1) /* battery */ |
38 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ | 41 | #define ISL1208_REG_SR_RTCF (1<<0) /* rtc fail */ |
39 | #define ISL1208_REG_INT 0x08 | 42 | #define ISL1208_REG_INT 0x08 |
40 | #define ISL1208_REG_INT_ALME (1<<6) /* alarm enable */ | 43 | #define ISL1208_REG_INT_ALME (1<<6) /* alarm enable */ |
41 | #define ISL1208_REG_INT_IM (1<<7) /* interrupt/alarm mode */ | 44 | #define ISL1208_REG_INT_IM (1<<7) /* interrupt/alarm mode */ |
42 | #define ISL1208_REG_09 0x09 /* reserved */ | 45 | #define ISL1219_REG_EV 0x09 |
46 | #define ISL1219_REG_EV_EVEN (1<<4) /* event detection enable */ | ||
47 | #define ISL1219_REG_EV_EVIENB (1<<7) /* event in pull-up disable */ | ||
43 | #define ISL1208_REG_ATR 0x0a | 48 | #define ISL1208_REG_ATR 0x0a |
44 | #define ISL1208_REG_DTR 0x0b | 49 | #define ISL1208_REG_DTR 0x0b |
45 | 50 | ||
@@ -57,8 +62,24 @@ | |||
57 | #define ISL1208_REG_USR2 0x13 | 62 | #define ISL1208_REG_USR2 0x13 |
58 | #define ISL1208_USR_SECTION_LEN 2 | 63 | #define ISL1208_USR_SECTION_LEN 2 |
59 | 64 | ||
65 | /* event section */ | ||
66 | #define ISL1219_REG_SCT 0x14 | ||
67 | #define ISL1219_REG_MNT 0x15 | ||
68 | #define ISL1219_REG_HRT 0x16 | ||
69 | #define ISL1219_REG_DTT 0x17 | ||
70 | #define ISL1219_REG_MOT 0x18 | ||
71 | #define ISL1219_REG_YRT 0x19 | ||
72 | #define ISL1219_EVT_SECTION_LEN 6 | ||
73 | |||
60 | static struct i2c_driver isl1208_driver; | 74 | static struct i2c_driver isl1208_driver; |
61 | 75 | ||
76 | /* ISL1208 various variants */ | ||
77 | enum { | ||
78 | TYPE_ISL1208 = 0, | ||
79 | TYPE_ISL1218, | ||
80 | TYPE_ISL1219, | ||
81 | }; | ||
82 | |||
62 | /* block read */ | 83 | /* block read */ |
63 | static int | 84 | static int |
64 | isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | 85 | isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], |
@@ -80,8 +101,8 @@ isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[], | |||
80 | }; | 101 | }; |
81 | int ret; | 102 | int ret; |
82 | 103 | ||
83 | BUG_ON(reg > ISL1208_REG_USR2); | 104 | WARN_ON(reg > ISL1219_REG_YRT); |
84 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); | 105 | WARN_ON(reg + len > ISL1219_REG_YRT + 1); |
85 | 106 | ||
86 | ret = i2c_transfer(client->adapter, msgs, 2); | 107 | ret = i2c_transfer(client->adapter, msgs, 2); |
87 | if (ret > 0) | 108 | if (ret > 0) |
@@ -104,8 +125,8 @@ isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[], | |||
104 | }; | 125 | }; |
105 | int ret; | 126 | int ret; |
106 | 127 | ||
107 | BUG_ON(reg > ISL1208_REG_USR2); | 128 | WARN_ON(reg > ISL1219_REG_YRT); |
108 | BUG_ON(reg + len > ISL1208_REG_USR2 + 1); | 129 | WARN_ON(reg + len > ISL1219_REG_YRT + 1); |
109 | 130 | ||
110 | i2c_buf[0] = reg; | 131 | i2c_buf[0] = reg; |
111 | memcpy(&i2c_buf[1], &buf[0], len); | 132 | memcpy(&i2c_buf[1], &buf[0], len); |
@@ -493,6 +514,73 @@ isl1208_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) | |||
493 | return isl1208_i2c_set_alarm(to_i2c_client(dev), alarm); | 514 | return isl1208_i2c_set_alarm(to_i2c_client(dev), alarm); |
494 | } | 515 | } |
495 | 516 | ||
517 | static ssize_t timestamp0_store(struct device *dev, | ||
518 | struct device_attribute *attr, | ||
519 | const char *buf, size_t count) | ||
520 | { | ||
521 | struct i2c_client *client = dev_get_drvdata(dev); | ||
522 | int sr; | ||
523 | |||
524 | sr = isl1208_i2c_get_sr(client); | ||
525 | if (sr < 0) { | ||
526 | dev_err(dev, "%s: reading SR failed\n", __func__); | ||
527 | return sr; | ||
528 | } | ||
529 | |||
530 | sr &= ~ISL1208_REG_SR_EVT; | ||
531 | |||
532 | sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); | ||
533 | if (sr < 0) | ||
534 | dev_err(dev, "%s: writing SR failed\n", | ||
535 | __func__); | ||
536 | |||
537 | return count; | ||
538 | }; | ||
539 | |||
540 | static ssize_t timestamp0_show(struct device *dev, | ||
541 | struct device_attribute *attr, char *buf) | ||
542 | { | ||
543 | struct i2c_client *client = dev_get_drvdata(dev); | ||
544 | u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, }; | ||
545 | struct rtc_time tm; | ||
546 | int sr; | ||
547 | |||
548 | sr = isl1208_i2c_get_sr(client); | ||
549 | if (sr < 0) { | ||
550 | dev_err(dev, "%s: reading SR failed\n", __func__); | ||
551 | return sr; | ||
552 | } | ||
553 | |||
554 | if (!(sr & ISL1208_REG_SR_EVT)) | ||
555 | return 0; | ||
556 | |||
557 | sr = isl1208_i2c_read_regs(client, ISL1219_REG_SCT, regs, | ||
558 | ISL1219_EVT_SECTION_LEN); | ||
559 | if (sr < 0) { | ||
560 | dev_err(dev, "%s: reading event section failed\n", | ||
561 | __func__); | ||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | /* MSB of each alarm register is an enable bit */ | ||
566 | tm.tm_sec = bcd2bin(regs[ISL1219_REG_SCT - ISL1219_REG_SCT] & 0x7f); | ||
567 | tm.tm_min = bcd2bin(regs[ISL1219_REG_MNT - ISL1219_REG_SCT] & 0x7f); | ||
568 | tm.tm_hour = bcd2bin(regs[ISL1219_REG_HRT - ISL1219_REG_SCT] & 0x3f); | ||
569 | tm.tm_mday = bcd2bin(regs[ISL1219_REG_DTT - ISL1219_REG_SCT] & 0x3f); | ||
570 | tm.tm_mon = | ||
571 | bcd2bin(regs[ISL1219_REG_MOT - ISL1219_REG_SCT] & 0x1f) - 1; | ||
572 | tm.tm_year = bcd2bin(regs[ISL1219_REG_YRT - ISL1219_REG_SCT]) + 100; | ||
573 | |||
574 | sr = rtc_valid_tm(&tm); | ||
575 | if (sr) | ||
576 | return sr; | ||
577 | |||
578 | return sprintf(buf, "%llu\n", | ||
579 | (unsigned long long)rtc_tm_to_time64(&tm)); | ||
580 | }; | ||
581 | |||
582 | static DEVICE_ATTR_RW(timestamp0); | ||
583 | |||
496 | static irqreturn_t | 584 | static irqreturn_t |
497 | isl1208_rtc_interrupt(int irq, void *data) | 585 | isl1208_rtc_interrupt(int irq, void *data) |
498 | { | 586 | { |
@@ -538,6 +626,13 @@ isl1208_rtc_interrupt(int irq, void *data) | |||
538 | return err; | 626 | return err; |
539 | } | 627 | } |
540 | 628 | ||
629 | if (sr & ISL1208_REG_SR_EVT) { | ||
630 | sysfs_notify(&rtc->dev.kobj, NULL, | ||
631 | dev_attr_timestamp0.attr.name); | ||
632 | dev_warn(&client->dev, "event detected"); | ||
633 | handled = 1; | ||
634 | } | ||
635 | |||
541 | return handled ? IRQ_HANDLED : IRQ_NONE; | 636 | return handled ? IRQ_HANDLED : IRQ_NONE; |
542 | } | 637 | } |
543 | 638 | ||
@@ -623,11 +718,39 @@ static const struct attribute_group isl1208_rtc_sysfs_files = { | |||
623 | .attrs = isl1208_rtc_attrs, | 718 | .attrs = isl1208_rtc_attrs, |
624 | }; | 719 | }; |
625 | 720 | ||
721 | static struct attribute *isl1219_rtc_attrs[] = { | ||
722 | &dev_attr_timestamp0.attr, | ||
723 | NULL | ||
724 | }; | ||
725 | |||
726 | static const struct attribute_group isl1219_rtc_sysfs_files = { | ||
727 | .attrs = isl1219_rtc_attrs, | ||
728 | }; | ||
729 | |||
730 | static int isl1208_setup_irq(struct i2c_client *client, int irq) | ||
731 | { | ||
732 | int rc = devm_request_threaded_irq(&client->dev, irq, NULL, | ||
733 | isl1208_rtc_interrupt, | ||
734 | IRQF_SHARED | IRQF_ONESHOT, | ||
735 | isl1208_driver.driver.name, | ||
736 | client); | ||
737 | if (!rc) { | ||
738 | device_init_wakeup(&client->dev, 1); | ||
739 | enable_irq_wake(irq); | ||
740 | } else { | ||
741 | dev_err(&client->dev, | ||
742 | "Unable to request irq %d, no alarm support\n", | ||
743 | irq); | ||
744 | } | ||
745 | return rc; | ||
746 | } | ||
747 | |||
626 | static int | 748 | static int |
627 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | 749 | isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) |
628 | { | 750 | { |
629 | int rc = 0; | 751 | int rc = 0; |
630 | struct rtc_device *rtc; | 752 | struct rtc_device *rtc; |
753 | int evdet_irq = -1; | ||
631 | 754 | ||
632 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | 755 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
633 | return -ENODEV; | 756 | return -ENODEV; |
@@ -642,6 +765,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
642 | rtc->ops = &isl1208_rtc_ops; | 765 | rtc->ops = &isl1208_rtc_ops; |
643 | 766 | ||
644 | i2c_set_clientdata(client, rtc); | 767 | i2c_set_clientdata(client, rtc); |
768 | dev_set_drvdata(&rtc->dev, client); | ||
645 | 769 | ||
646 | rc = isl1208_i2c_get_sr(client); | 770 | rc = isl1208_i2c_get_sr(client); |
647 | if (rc < 0) { | 771 | if (rc < 0) { |
@@ -653,26 +777,46 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
653 | dev_warn(&client->dev, "rtc power failure detected, " | 777 | dev_warn(&client->dev, "rtc power failure detected, " |
654 | "please set clock.\n"); | 778 | "please set clock.\n"); |
655 | 779 | ||
780 | if (id->driver_data == TYPE_ISL1219) { | ||
781 | struct device_node *np = client->dev.of_node; | ||
782 | u32 evienb; | ||
783 | |||
784 | rc = i2c_smbus_read_byte_data(client, ISL1219_REG_EV); | ||
785 | if (rc < 0) { | ||
786 | dev_err(&client->dev, "failed to read EV reg\n"); | ||
787 | return rc; | ||
788 | } | ||
789 | rc |= ISL1219_REG_EV_EVEN; | ||
790 | if (!of_property_read_u32(np, "isil,ev-evienb", &evienb)) { | ||
791 | if (evienb) | ||
792 | rc |= ISL1219_REG_EV_EVIENB; | ||
793 | else | ||
794 | rc &= ~ISL1219_REG_EV_EVIENB; | ||
795 | } | ||
796 | rc = i2c_smbus_write_byte_data(client, ISL1219_REG_EV, rc); | ||
797 | if (rc < 0) { | ||
798 | dev_err(&client->dev, "could not enable tamper detection\n"); | ||
799 | return rc; | ||
800 | } | ||
801 | rc = rtc_add_group(rtc, &isl1219_rtc_sysfs_files); | ||
802 | if (rc) | ||
803 | return rc; | ||
804 | evdet_irq = of_irq_get_byname(np, "evdet"); | ||
805 | } | ||
806 | |||
656 | rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); | 807 | rc = sysfs_create_group(&client->dev.kobj, &isl1208_rtc_sysfs_files); |
657 | if (rc) | 808 | if (rc) |
658 | return rc; | 809 | return rc; |
659 | 810 | ||
660 | if (client->irq > 0) { | 811 | if (client->irq > 0) |
661 | rc = devm_request_threaded_irq(&client->dev, client->irq, NULL, | 812 | rc = isl1208_setup_irq(client, client->irq); |
662 | isl1208_rtc_interrupt, | 813 | if (rc) |
663 | IRQF_SHARED | IRQF_ONESHOT, | 814 | return rc; |
664 | isl1208_driver.driver.name, | 815 | |
665 | client); | 816 | if (evdet_irq > 0 && evdet_irq != client->irq) |
666 | if (!rc) { | 817 | rc = isl1208_setup_irq(client, evdet_irq); |
667 | device_init_wakeup(&client->dev, 1); | 818 | if (rc) |
668 | enable_irq_wake(client->irq); | 819 | return rc; |
669 | } else { | ||
670 | dev_err(&client->dev, | ||
671 | "Unable to request irq %d, no alarm support\n", | ||
672 | client->irq); | ||
673 | client->irq = 0; | ||
674 | } | ||
675 | } | ||
676 | 820 | ||
677 | return rtc_register_device(rtc); | 821 | return rtc_register_device(rtc); |
678 | } | 822 | } |
@@ -686,8 +830,9 @@ isl1208_remove(struct i2c_client *client) | |||
686 | } | 830 | } |
687 | 831 | ||
688 | static const struct i2c_device_id isl1208_id[] = { | 832 | static const struct i2c_device_id isl1208_id[] = { |
689 | { "isl1208", 0 }, | 833 | { "isl1208", TYPE_ISL1208 }, |
690 | { "isl1218", 0 }, | 834 | { "isl1218", TYPE_ISL1218 }, |
835 | { "isl1219", TYPE_ISL1219 }, | ||
691 | { } | 836 | { } |
692 | }; | 837 | }; |
693 | MODULE_DEVICE_TABLE(i2c, isl1208_id); | 838 | MODULE_DEVICE_TABLE(i2c, isl1208_id); |
@@ -695,6 +840,7 @@ MODULE_DEVICE_TABLE(i2c, isl1208_id); | |||
695 | static const struct of_device_id isl1208_of_match[] = { | 840 | static const struct of_device_id isl1208_of_match[] = { |
696 | { .compatible = "isil,isl1208" }, | 841 | { .compatible = "isil,isl1208" }, |
697 | { .compatible = "isil,isl1218" }, | 842 | { .compatible = "isil,isl1218" }, |
843 | { .compatible = "isil,isl1219" }, | ||
698 | { } | 844 | { } |
699 | }; | 845 | }; |
700 | MODULE_DEVICE_TABLE(of, isl1208_of_match); | 846 | MODULE_DEVICE_TABLE(of, isl1208_of_match); |
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c index 1053a406b3aa..ac9ca1042889 100644 --- a/drivers/rtc/rtc-m48t59.c +++ b/drivers/rtc/rtc-m48t59.c | |||
@@ -373,7 +373,6 @@ static int m48t59_rtc_probe(struct platform_device *pdev) | |||
373 | struct m48t59_private *m48t59 = NULL; | 373 | struct m48t59_private *m48t59 = NULL; |
374 | struct resource *res; | 374 | struct resource *res; |
375 | int ret = -ENOMEM; | 375 | int ret = -ENOMEM; |
376 | char *name; | ||
377 | const struct rtc_class_ops *ops; | 376 | const struct rtc_class_ops *ops; |
378 | struct nvmem_config nvmem_cfg = { | 377 | struct nvmem_config nvmem_cfg = { |
379 | .name = "m48t59-", | 378 | .name = "m48t59-", |
@@ -448,17 +447,14 @@ static int m48t59_rtc_probe(struct platform_device *pdev) | |||
448 | } | 447 | } |
449 | switch (pdata->type) { | 448 | switch (pdata->type) { |
450 | case M48T59RTC_TYPE_M48T59: | 449 | case M48T59RTC_TYPE_M48T59: |
451 | name = "m48t59"; | ||
452 | ops = &m48t59_rtc_ops; | 450 | ops = &m48t59_rtc_ops; |
453 | pdata->offset = 0x1ff0; | 451 | pdata->offset = 0x1ff0; |
454 | break; | 452 | break; |
455 | case M48T59RTC_TYPE_M48T02: | 453 | case M48T59RTC_TYPE_M48T02: |
456 | name = "m48t02"; | ||
457 | ops = &m48t02_rtc_ops; | 454 | ops = &m48t02_rtc_ops; |
458 | pdata->offset = 0x7f0; | 455 | pdata->offset = 0x7f0; |
459 | break; | 456 | break; |
460 | case M48T59RTC_TYPE_M48T08: | 457 | case M48T59RTC_TYPE_M48T08: |
461 | name = "m48t08"; | ||
462 | ops = &m48t02_rtc_ops; | 458 | ops = &m48t02_rtc_ops; |
463 | pdata->offset = 0x1ff0; | 459 | pdata->offset = 0x1ff0; |
464 | break; | 460 | break; |
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index cefde273fae6..8a60900d6b8b 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c | |||
@@ -1,16 +1,10 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * RTC driver for Maxim MAX77686 and MAX77802 | 2 | // |
3 | * | 3 | // RTC driver for Maxim MAX77686 and MAX77802 |
4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | 4 | // |
5 | * | 5 | // Copyright (C) 2012 Samsung Electronics Co.Ltd |
6 | * based on rtc-max8997.c | 6 | // |
7 | * | 7 | // based on rtc-max8997.c |
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | 8 | ||
15 | #include <linux/i2c.h> | 9 | #include <linux/i2c.h> |
16 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
diff --git a/drivers/rtc/rtc-max8997.c b/drivers/rtc/rtc-max8997.c index e8cee123e8aa..08c661a332ec 100644 --- a/drivers/rtc/rtc-max8997.c +++ b/drivers/rtc/rtc-max8997.c | |||
@@ -1,16 +1,10 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * RTC driver for Maxim MAX8997 | 2 | // |
3 | * | 3 | // RTC driver for Maxim MAX8997 |
4 | * Copyright (C) 2013 Samsung Electronics Co.Ltd | 4 | // |
5 | * | 5 | // Copyright (C) 2013 Samsung Electronics Co.Ltd |
6 | * based on rtc-max8998.c | 6 | // |
7 | * | 7 | // based on rtc-max8998.c |
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | 8 | ||
15 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
16 | 10 | ||
diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index d8c0f9b3f87d..c873b4509b3c 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c | |||
@@ -1,16 +1,10 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * RTC driver for Maxim MAX8998 | 2 | // |
3 | * | 3 | // RTC driver for Maxim MAX8998 |
4 | * Copyright (C) 2010 Samsung Electronics Co.Ltd | 4 | // |
5 | * Author: Minkyu Kang <mk7.kang@samsung.com> | 5 | // Copyright (C) 2010 Samsung Electronics Co.Ltd |
6 | * Author: Joonyoung Shim <jy0922.shim@samsung.com> | 6 | // Author: Minkyu Kang <mk7.kang@samsung.com> |
7 | * | 7 | // Author: Joonyoung Shim <jy0922.shim@samsung.com> |
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | */ | ||
14 | 8 | ||
15 | #include <linux/module.h> | 9 | #include <linux/module.h> |
16 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 39086398833e..323ff55cc165 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -449,6 +449,7 @@ static void omap_rtc_power_off(void) | |||
449 | 449 | ||
450 | if (tm2bcd(&tm) < 0) { | 450 | if (tm2bcd(&tm) < 0) { |
451 | dev_err(&rtc->rtc->dev, "power off failed\n"); | 451 | dev_err(&rtc->rtc->dev, "power off failed\n"); |
452 | rtc->type->lock(rtc); | ||
452 | return; | 453 | return; |
453 | } | 454 | } |
454 | 455 | ||
@@ -582,9 +583,7 @@ static int rtc_pinconf_get(struct pinctrl_dev *pctldev, | |||
582 | u32 val; | 583 | u32 val; |
583 | u16 arg = 0; | 584 | u16 arg = 0; |
584 | 585 | ||
585 | rtc->type->unlock(rtc); | ||
586 | val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); | 586 | val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); |
587 | rtc->type->lock(rtc); | ||
588 | 587 | ||
589 | switch (param) { | 588 | switch (param) { |
590 | case PIN_CONFIG_INPUT_ENABLE: | 589 | case PIN_CONFIG_INPUT_ENABLE: |
@@ -614,9 +613,7 @@ static int rtc_pinconf_set(struct pinctrl_dev *pctldev, | |||
614 | u32 param_val; | 613 | u32 param_val; |
615 | int i; | 614 | int i; |
616 | 615 | ||
617 | rtc->type->unlock(rtc); | ||
618 | val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); | 616 | val = rtc_readl(rtc, OMAP_RTC_PMIC_REG); |
619 | rtc->type->lock(rtc); | ||
620 | 617 | ||
621 | /* active low by default */ | 618 | /* active low by default */ |
622 | val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin); | 619 | val |= OMAP_RTC_PMIC_EXT_WKUP_POL(pin); |
@@ -861,13 +858,6 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
861 | goto err; | 858 | goto err; |
862 | } | 859 | } |
863 | 860 | ||
864 | if (rtc->is_pmic_controller) { | ||
865 | if (!pm_power_off) { | ||
866 | omap_rtc_power_off_rtc = rtc; | ||
867 | pm_power_off = omap_rtc_power_off; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /* Support ext_wakeup pinconf */ | 861 | /* Support ext_wakeup pinconf */ |
872 | rtc_pinctrl_desc.name = dev_name(&pdev->dev); | 862 | rtc_pinctrl_desc.name = dev_name(&pdev->dev); |
873 | 863 | ||
@@ -880,12 +870,21 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
880 | 870 | ||
881 | ret = rtc_register_device(rtc->rtc); | 871 | ret = rtc_register_device(rtc->rtc); |
882 | if (ret) | 872 | if (ret) |
883 | goto err; | 873 | goto err_deregister_pinctrl; |
884 | 874 | ||
885 | rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config); | 875 | rtc_nvmem_register(rtc->rtc, &omap_rtc_nvmem_config); |
886 | 876 | ||
877 | if (rtc->is_pmic_controller) { | ||
878 | if (!pm_power_off) { | ||
879 | omap_rtc_power_off_rtc = rtc; | ||
880 | pm_power_off = omap_rtc_power_off; | ||
881 | } | ||
882 | } | ||
883 | |||
887 | return 0; | 884 | return 0; |
888 | 885 | ||
886 | err_deregister_pinctrl: | ||
887 | pinctrl_unregister(rtc->pctldev); | ||
889 | err: | 888 | err: |
890 | clk_disable_unprepare(rtc->clk); | 889 | clk_disable_unprepare(rtc->clk); |
891 | device_init_wakeup(&pdev->dev, false); | 890 | device_init_wakeup(&pdev->dev, false); |
diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index e83be1852c2f..9f99a0966550 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c | |||
@@ -36,6 +36,11 @@ | |||
36 | #define PCF2127_REG_MO (0x08) | 36 | #define PCF2127_REG_MO (0x08) |
37 | #define PCF2127_REG_YR (0x09) | 37 | #define PCF2127_REG_YR (0x09) |
38 | 38 | ||
39 | /* the pcf2127 has 512 bytes nvmem, pcf2129 doesn't */ | ||
40 | #define PCF2127_REG_RAM_addr_MSB 0x1a | ||
41 | #define PCF2127_REG_RAM_wrt_cmd 0x1c | ||
42 | #define PCF2127_REG_RAM_rd_cmd 0x1d | ||
43 | |||
39 | #define PCF2127_OSF BIT(7) /* Oscillator Fail flag */ | 44 | #define PCF2127_OSF BIT(7) /* Oscillator Fail flag */ |
40 | 45 | ||
41 | struct pcf2127 { | 46 | struct pcf2127 { |
@@ -183,10 +188,47 @@ static const struct rtc_class_ops pcf2127_rtc_ops = { | |||
183 | .set_time = pcf2127_rtc_set_time, | 188 | .set_time = pcf2127_rtc_set_time, |
184 | }; | 189 | }; |
185 | 190 | ||
191 | static int pcf2127_nvmem_read(void *priv, unsigned int offset, | ||
192 | void *val, size_t bytes) | ||
193 | { | ||
194 | struct pcf2127 *pcf2127 = priv; | ||
195 | int ret; | ||
196 | unsigned char offsetbuf[] = { offset >> 8, offset }; | ||
197 | |||
198 | ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB, | ||
199 | offsetbuf, 2); | ||
200 | if (ret) | ||
201 | return ret; | ||
202 | |||
203 | ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_RAM_rd_cmd, | ||
204 | val, bytes); | ||
205 | |||
206 | return ret ?: bytes; | ||
207 | } | ||
208 | |||
209 | static int pcf2127_nvmem_write(void *priv, unsigned int offset, | ||
210 | void *val, size_t bytes) | ||
211 | { | ||
212 | struct pcf2127 *pcf2127 = priv; | ||
213 | int ret; | ||
214 | unsigned char offsetbuf[] = { offset >> 8, offset }; | ||
215 | |||
216 | ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_addr_MSB, | ||
217 | offsetbuf, 2); | ||
218 | if (ret) | ||
219 | return ret; | ||
220 | |||
221 | ret = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_wrt_cmd, | ||
222 | val, bytes); | ||
223 | |||
224 | return ret ?: bytes; | ||
225 | } | ||
226 | |||
186 | static int pcf2127_probe(struct device *dev, struct regmap *regmap, | 227 | static int pcf2127_probe(struct device *dev, struct regmap *regmap, |
187 | const char *name) | 228 | const char *name, bool has_nvmem) |
188 | { | 229 | { |
189 | struct pcf2127 *pcf2127; | 230 | struct pcf2127 *pcf2127; |
231 | int ret = 0; | ||
190 | 232 | ||
191 | dev_dbg(dev, "%s\n", __func__); | 233 | dev_dbg(dev, "%s\n", __func__); |
192 | 234 | ||
@@ -200,8 +242,21 @@ static int pcf2127_probe(struct device *dev, struct regmap *regmap, | |||
200 | 242 | ||
201 | pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops, | 243 | pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops, |
202 | THIS_MODULE); | 244 | THIS_MODULE); |
245 | if (IS_ERR(pcf2127->rtc)) | ||
246 | return PTR_ERR(pcf2127->rtc); | ||
247 | |||
248 | if (has_nvmem) { | ||
249 | struct nvmem_config nvmem_cfg = { | ||
250 | .priv = pcf2127, | ||
251 | .reg_read = pcf2127_nvmem_read, | ||
252 | .reg_write = pcf2127_nvmem_write, | ||
253 | .size = 512, | ||
254 | }; | ||
255 | |||
256 | ret = rtc_nvmem_register(pcf2127->rtc, &nvmem_cfg); | ||
257 | } | ||
203 | 258 | ||
204 | return PTR_ERR_OR_ZERO(pcf2127->rtc); | 259 | return ret; |
205 | } | 260 | } |
206 | 261 | ||
207 | #ifdef CONFIG_OF | 262 | #ifdef CONFIG_OF |
@@ -309,11 +364,11 @@ static int pcf2127_i2c_probe(struct i2c_client *client, | |||
309 | } | 364 | } |
310 | 365 | ||
311 | return pcf2127_probe(&client->dev, regmap, | 366 | return pcf2127_probe(&client->dev, regmap, |
312 | pcf2127_i2c_driver.driver.name); | 367 | pcf2127_i2c_driver.driver.name, id->driver_data); |
313 | } | 368 | } |
314 | 369 | ||
315 | static const struct i2c_device_id pcf2127_i2c_id[] = { | 370 | static const struct i2c_device_id pcf2127_i2c_id[] = { |
316 | { "pcf2127", 0 }, | 371 | { "pcf2127", 1 }, |
317 | { "pcf2129", 0 }, | 372 | { "pcf2129", 0 }, |
318 | { } | 373 | { } |
319 | }; | 374 | }; |
@@ -372,11 +427,12 @@ static int pcf2127_spi_probe(struct spi_device *spi) | |||
372 | return PTR_ERR(regmap); | 427 | return PTR_ERR(regmap); |
373 | } | 428 | } |
374 | 429 | ||
375 | return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name); | 430 | return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name, |
431 | spi_get_device_id(spi)->driver_data); | ||
376 | } | 432 | } |
377 | 433 | ||
378 | static const struct spi_device_id pcf2127_spi_id[] = { | 434 | static const struct spi_device_id pcf2127_spi_id[] = { |
379 | { "pcf2127", 0 }, | 435 | { "pcf2127", 1 }, |
380 | { "pcf2129", 0 }, | 436 | { "pcf2129", 0 }, |
381 | { } | 437 | { } |
382 | }; | 438 | }; |
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 49bcbb3d4a69..283c2335b01b 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c | |||
@@ -43,37 +43,38 @@ static struct i2c_driver pcf85063_driver; | |||
43 | 43 | ||
44 | static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1) | 44 | static int pcf85063_stop_clock(struct i2c_client *client, u8 *ctrl1) |
45 | { | 45 | { |
46 | s32 ret; | 46 | int rc; |
47 | u8 reg; | ||
47 | 48 | ||
48 | ret = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1); | 49 | rc = i2c_smbus_read_byte_data(client, PCF85063_REG_CTRL1); |
49 | if (ret < 0) { | 50 | if (rc < 0) { |
50 | dev_err(&client->dev, "Failing to stop the clock\n"); | 51 | dev_err(&client->dev, "Failing to stop the clock\n"); |
51 | return -EIO; | 52 | return -EIO; |
52 | } | 53 | } |
53 | 54 | ||
54 | /* stop the clock */ | 55 | /* stop the clock */ |
55 | ret |= PCF85063_REG_CTRL1_STOP; | 56 | reg = rc | PCF85063_REG_CTRL1_STOP; |
56 | 57 | ||
57 | ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ret); | 58 | rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, reg); |
58 | if (ret < 0) { | 59 | if (rc < 0) { |
59 | dev_err(&client->dev, "Failing to stop the clock\n"); | 60 | dev_err(&client->dev, "Failing to stop the clock\n"); |
60 | return -EIO; | 61 | return -EIO; |
61 | } | 62 | } |
62 | 63 | ||
63 | *ctrl1 = ret; | 64 | *ctrl1 = reg; |
64 | 65 | ||
65 | return 0; | 66 | return 0; |
66 | } | 67 | } |
67 | 68 | ||
68 | static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) | 69 | static int pcf85063_start_clock(struct i2c_client *client, u8 ctrl1) |
69 | { | 70 | { |
70 | s32 ret; | 71 | int rc; |
71 | 72 | ||
72 | /* start the clock */ | 73 | /* start the clock */ |
73 | ctrl1 &= ~PCF85063_REG_CTRL1_STOP; | 74 | ctrl1 &= ~PCF85063_REG_CTRL1_STOP; |
74 | 75 | ||
75 | ret = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); | 76 | rc = i2c_smbus_write_byte_data(client, PCF85063_REG_CTRL1, ctrl1); |
76 | if (ret < 0) { | 77 | if (rc < 0) { |
77 | dev_err(&client->dev, "Failing to start the clock\n"); | 78 | dev_err(&client->dev, "Failing to start the clock\n"); |
78 | return -EIO; | 79 | return -EIO; |
79 | } | 80 | } |
diff --git a/drivers/rtc/rtc-s5m.c b/drivers/rtc/rtc-s5m.c index 8428455432ca..6495f84f7428 100644 --- a/drivers/rtc/rtc-s5m.c +++ b/drivers/rtc/rtc-s5m.c | |||
@@ -1,19 +1,9 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd | 2 | // |
3 | * http://www.samsung.com | 3 | // Copyright (c) 2013-2014 Samsung Electronics Co., Ltd |
4 | * | 4 | // http://www.samsung.com |
5 | * Copyright (C) 2013 Google, Inc | 5 | // |
6 | * | 6 | // Copyright (C) 2013 Google, Inc |
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | 7 | ||
18 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
19 | 9 | ||
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index ed71d1113627..304d905cb23f 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -224,7 +224,6 @@ int sa1100_rtc_init(struct platform_device *pdev, struct sa1100_rtc *info) | |||
224 | info->rtc = rtc; | 224 | info->rtc = rtc; |
225 | 225 | ||
226 | rtc->max_user_freq = RTC_FREQ; | 226 | rtc->max_user_freq = RTC_FREQ; |
227 | rtc_irq_set_freq(rtc, NULL, RTC_FREQ); | ||
228 | 227 | ||
229 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. | 228 | /* Fix for a nasty initialization problem the in SA11xx RTSR register. |
230 | * See also the comments in sa1100_rtc_interrupt(). | 229 | * See also the comments in sa1100_rtc_interrupt(). |
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 776b70a14e03..51ba414798a8 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c | |||
@@ -143,8 +143,6 @@ static int __sh_rtc_alarm(struct sh_rtc *rtc) | |||
143 | 143 | ||
144 | static int __sh_rtc_periodic(struct sh_rtc *rtc) | 144 | static int __sh_rtc_periodic(struct sh_rtc *rtc) |
145 | { | 145 | { |
146 | struct rtc_device *rtc_dev = rtc->rtc_dev; | ||
147 | struct rtc_task *irq_task; | ||
148 | unsigned int tmp, pending; | 146 | unsigned int tmp, pending; |
149 | 147 | ||
150 | tmp = readb(rtc->regbase + RCR2); | 148 | tmp = readb(rtc->regbase + RCR2); |
@@ -161,14 +159,7 @@ static int __sh_rtc_periodic(struct sh_rtc *rtc) | |||
161 | else { | 159 | else { |
162 | if (rtc->periodic_freq & PF_HP) | 160 | if (rtc->periodic_freq & PF_HP) |
163 | rtc->periodic_freq |= PF_COUNT; | 161 | rtc->periodic_freq |= PF_COUNT; |
164 | if (rtc->periodic_freq & PF_KOU) { | 162 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); |
165 | spin_lock(&rtc_dev->irq_task_lock); | ||
166 | irq_task = rtc_dev->irq_task; | ||
167 | if (irq_task) | ||
168 | irq_task->func(irq_task->private_data); | ||
169 | spin_unlock(&rtc_dev->irq_task_lock); | ||
170 | } else | ||
171 | rtc_update_irq(rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); | ||
172 | } | 163 | } |
173 | 164 | ||
174 | return pending; | 165 | return pending; |
@@ -224,81 +215,6 @@ static irqreturn_t sh_rtc_shared(int irq, void *dev_id) | |||
224 | return IRQ_RETVAL(ret); | 215 | return IRQ_RETVAL(ret); |
225 | } | 216 | } |
226 | 217 | ||
227 | static int sh_rtc_irq_set_state(struct device *dev, int enable) | ||
228 | { | ||
229 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
230 | unsigned int tmp; | ||
231 | |||
232 | spin_lock_irq(&rtc->lock); | ||
233 | |||
234 | tmp = readb(rtc->regbase + RCR2); | ||
235 | |||
236 | if (enable) { | ||
237 | rtc->periodic_freq |= PF_KOU; | ||
238 | tmp &= ~RCR2_PEF; /* Clear PES bit */ | ||
239 | tmp |= (rtc->periodic_freq & ~PF_HP); /* Set PES2-0 */ | ||
240 | } else { | ||
241 | rtc->periodic_freq &= ~PF_KOU; | ||
242 | tmp &= ~(RCR2_PESMASK | RCR2_PEF); | ||
243 | } | ||
244 | |||
245 | writeb(tmp, rtc->regbase + RCR2); | ||
246 | |||
247 | spin_unlock_irq(&rtc->lock); | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int sh_rtc_irq_set_freq(struct device *dev, int freq) | ||
253 | { | ||
254 | struct sh_rtc *rtc = dev_get_drvdata(dev); | ||
255 | int tmp, ret = 0; | ||
256 | |||
257 | spin_lock_irq(&rtc->lock); | ||
258 | tmp = rtc->periodic_freq & PF_MASK; | ||
259 | |||
260 | switch (freq) { | ||
261 | case 0: | ||
262 | rtc->periodic_freq = 0x00; | ||
263 | break; | ||
264 | case 1: | ||
265 | rtc->periodic_freq = 0x60; | ||
266 | break; | ||
267 | case 2: | ||
268 | rtc->periodic_freq = 0x50; | ||
269 | break; | ||
270 | case 4: | ||
271 | rtc->periodic_freq = 0x40; | ||
272 | break; | ||
273 | case 8: | ||
274 | rtc->periodic_freq = 0x30 | PF_HP; | ||
275 | break; | ||
276 | case 16: | ||
277 | rtc->periodic_freq = 0x30; | ||
278 | break; | ||
279 | case 32: | ||
280 | rtc->periodic_freq = 0x20 | PF_HP; | ||
281 | break; | ||
282 | case 64: | ||
283 | rtc->periodic_freq = 0x20; | ||
284 | break; | ||
285 | case 128: | ||
286 | rtc->periodic_freq = 0x10 | PF_HP; | ||
287 | break; | ||
288 | case 256: | ||
289 | rtc->periodic_freq = 0x10; | ||
290 | break; | ||
291 | default: | ||
292 | ret = -ENOTSUPP; | ||
293 | } | ||
294 | |||
295 | if (ret == 0) | ||
296 | rtc->periodic_freq |= tmp; | ||
297 | |||
298 | spin_unlock_irq(&rtc->lock); | ||
299 | return ret; | ||
300 | } | ||
301 | |||
302 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) | 218 | static inline void sh_rtc_setaie(struct device *dev, unsigned int enable) |
303 | { | 219 | { |
304 | struct sh_rtc *rtc = dev_get_drvdata(dev); | 220 | struct sh_rtc *rtc = dev_get_drvdata(dev); |
@@ -675,8 +591,6 @@ static int __init sh_rtc_probe(struct platform_device *pdev) | |||
675 | platform_set_drvdata(pdev, rtc); | 591 | platform_set_drvdata(pdev, rtc); |
676 | 592 | ||
677 | /* everything disabled by default */ | 593 | /* everything disabled by default */ |
678 | sh_rtc_irq_set_freq(&pdev->dev, 0); | ||
679 | sh_rtc_irq_set_state(&pdev->dev, 0); | ||
680 | sh_rtc_setaie(&pdev->dev, 0); | 594 | sh_rtc_setaie(&pdev->dev, 0); |
681 | sh_rtc_setcie(&pdev->dev, 0); | 595 | sh_rtc_setcie(&pdev->dev, 0); |
682 | 596 | ||
@@ -708,8 +622,6 @@ static int __exit sh_rtc_remove(struct platform_device *pdev) | |||
708 | { | 622 | { |
709 | struct sh_rtc *rtc = platform_get_drvdata(pdev); | 623 | struct sh_rtc *rtc = platform_get_drvdata(pdev); |
710 | 624 | ||
711 | sh_rtc_irq_set_state(&pdev->dev, 0); | ||
712 | |||
713 | sh_rtc_setaie(&pdev->dev, 0); | 625 | sh_rtc_setaie(&pdev->dev, 0); |
714 | sh_rtc_setcie(&pdev->dev, 0); | 626 | sh_rtc_setcie(&pdev->dev, 0); |
715 | 627 | ||
diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 8a75cc3af6e7..b2483a749ac4 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c | |||
@@ -40,49 +40,83 @@ struct snvs_rtc_data { | |||
40 | struct clk *clk; | 40 | struct clk *clk; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | /* Read 64 bit timer register, which could be in inconsistent state */ | ||
44 | static u64 rtc_read_lpsrt(struct snvs_rtc_data *data) | ||
45 | { | ||
46 | u32 msb, lsb; | ||
47 | |||
48 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &msb); | ||
49 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &lsb); | ||
50 | return (u64)msb << 32 | lsb; | ||
51 | } | ||
52 | |||
53 | /* Read the secure real time counter, taking care to deal with the cases of the | ||
54 | * counter updating while being read. | ||
55 | */ | ||
43 | static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) | 56 | static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) |
44 | { | 57 | { |
45 | u64 read1, read2; | 58 | u64 read1, read2; |
46 | u32 val; | 59 | unsigned int timeout = 100; |
47 | 60 | ||
61 | /* As expected, the registers might update between the read of the LSB | ||
62 | * reg and the MSB reg. It's also possible that one register might be | ||
63 | * in partially modified state as well. | ||
64 | */ | ||
65 | read1 = rtc_read_lpsrt(data); | ||
48 | do { | 66 | do { |
49 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); | 67 | read2 = read1; |
50 | read1 = val; | 68 | read1 = rtc_read_lpsrt(data); |
51 | read1 <<= 32; | 69 | } while (read1 != read2 && --timeout); |
52 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); | 70 | if (!timeout) |
53 | read1 |= val; | 71 | dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); |
54 | |||
55 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); | ||
56 | read2 = val; | ||
57 | read2 <<= 32; | ||
58 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); | ||
59 | read2 |= val; | ||
60 | } while (read1 != read2); | ||
61 | 72 | ||
62 | /* Convert 47-bit counter to 32-bit raw second count */ | 73 | /* Convert 47-bit counter to 32-bit raw second count */ |
63 | return (u32) (read1 >> CNTR_TO_SECS_SH); | 74 | return (u32) (read1 >> CNTR_TO_SECS_SH); |
64 | } | 75 | } |
65 | 76 | ||
66 | static void rtc_write_sync_lp(struct snvs_rtc_data *data) | 77 | /* Just read the lsb from the counter, dealing with inconsistent state */ |
78 | static int rtc_read_lp_counter_lsb(struct snvs_rtc_data *data, u32 *lsb) | ||
79 | { | ||
80 | u32 count1, count2; | ||
81 | unsigned int timeout = 100; | ||
82 | |||
83 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); | ||
84 | do { | ||
85 | count2 = count1; | ||
86 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); | ||
87 | } while (count1 != count2 && --timeout); | ||
88 | if (!timeout) { | ||
89 | dev_err(&data->rtc->dev, "Timeout trying to get valid LPSRT Counter read\n"); | ||
90 | return -ETIMEDOUT; | ||
91 | } | ||
92 | |||
93 | *lsb = count1; | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int rtc_write_sync_lp(struct snvs_rtc_data *data) | ||
67 | { | 98 | { |
68 | u32 count1, count2, count3; | 99 | u32 count1, count2; |
69 | int i; | 100 | u32 elapsed; |
70 | 101 | unsigned int timeout = 1000; | |
71 | /* Wait for 3 CKIL cycles */ | 102 | int ret; |
72 | for (i = 0; i < 3; i++) { | 103 | |
73 | do { | 104 | ret = rtc_read_lp_counter_lsb(data, &count1); |
74 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); | 105 | if (ret) |
75 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); | 106 | return ret; |
76 | } while (count1 != count2); | 107 | |
77 | 108 | /* Wait for 3 CKIL cycles, about 61.0-91.5 µs */ | |
78 | /* Now wait until counter value changes */ | 109 | do { |
79 | do { | 110 | ret = rtc_read_lp_counter_lsb(data, &count2); |
80 | do { | 111 | if (ret) |
81 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); | 112 | return ret; |
82 | regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3); | 113 | elapsed = count2 - count1; /* wrap around _is_ handled! */ |
83 | } while (count2 != count3); | 114 | } while (elapsed < 3 && --timeout); |
84 | } while (count3 == count1); | 115 | if (!timeout) { |
116 | dev_err(&data->rtc->dev, "Timeout waiting for LPSRT Counter to change\n"); | ||
117 | return -ETIMEDOUT; | ||
85 | } | 118 | } |
119 | return 0; | ||
86 | } | 120 | } |
87 | 121 | ||
88 | static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) | 122 | static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) |
@@ -166,9 +200,7 @@ static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | |||
166 | (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), | 200 | (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), |
167 | enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); | 201 | enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); |
168 | 202 | ||
169 | rtc_write_sync_lp(data); | 203 | return rtc_write_sync_lp(data); |
170 | |||
171 | return 0; | ||
172 | } | 204 | } |
173 | 205 | ||
174 | static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 206 | static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
@@ -176,11 +208,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
176 | struct snvs_rtc_data *data = dev_get_drvdata(dev); | 208 | struct snvs_rtc_data *data = dev_get_drvdata(dev); |
177 | struct rtc_time *alrm_tm = &alrm->time; | 209 | struct rtc_time *alrm_tm = &alrm->time; |
178 | unsigned long time; | 210 | unsigned long time; |
211 | int ret; | ||
179 | 212 | ||
180 | rtc_tm_to_time(alrm_tm, &time); | 213 | rtc_tm_to_time(alrm_tm, &time); |
181 | 214 | ||
182 | regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); | 215 | regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); |
183 | rtc_write_sync_lp(data); | 216 | ret = rtc_write_sync_lp(data); |
217 | if (ret) | ||
218 | return ret; | ||
184 | regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); | 219 | regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); |
185 | 220 | ||
186 | /* Clear alarm interrupt status bit */ | 221 | /* Clear alarm interrupt status bit */ |
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index d578e40d5a50..b76318fd5bb0 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -288,10 +288,22 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) | |||
288 | 288 | ||
289 | platform_set_drvdata(pdev, rtc_data); | 289 | platform_set_drvdata(pdev, rtc_data); |
290 | 290 | ||
291 | err = stmp_reset_block(rtc_data->io); | 291 | /* |
292 | if (err) { | 292 | * Resetting the rtc stops the watchdog timer that is potentially |
293 | dev_err(&pdev->dev, "stmp_reset_block failed: %d\n", err); | 293 | * running. So (assuming it is running on purpose) don't reset if the |
294 | return err; | 294 | * watchdog is enabled. |
295 | */ | ||
296 | if (readl(rtc_data->io + STMP3XXX_RTC_CTRL) & | ||
297 | STMP3XXX_RTC_CTRL_WATCHDOGEN) { | ||
298 | dev_info(&pdev->dev, | ||
299 | "Watchdog is running, skip resetting rtc\n"); | ||
300 | } else { | ||
301 | err = stmp_reset_block(rtc_data->io); | ||
302 | if (err) { | ||
303 | dev_err(&pdev->dev, "stmp_reset_block failed: %d\n", | ||
304 | err); | ||
305 | return err; | ||
306 | } | ||
295 | } | 307 | } |
296 | 308 | ||
297 | /* | 309 | /* |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 454da38c6012..f1ff30ade534 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -317,3 +317,46 @@ const struct attribute_group **rtc_get_dev_attribute_groups(void) | |||
317 | { | 317 | { |
318 | return rtc_attr_groups; | 318 | return rtc_attr_groups; |
319 | } | 319 | } |
320 | |||
321 | int rtc_add_groups(struct rtc_device *rtc, const struct attribute_group **grps) | ||
322 | { | ||
323 | size_t old_cnt = 0, add_cnt = 0, new_cnt; | ||
324 | const struct attribute_group **groups, **old; | ||
325 | |||
326 | if (rtc->registered) | ||
327 | return -EINVAL; | ||
328 | if (!grps) | ||
329 | return -EINVAL; | ||
330 | |||
331 | groups = rtc->dev.groups; | ||
332 | if (groups) | ||
333 | for (; *groups; groups++) | ||
334 | old_cnt++; | ||
335 | |||
336 | for (groups = grps; *groups; groups++) | ||
337 | add_cnt++; | ||
338 | |||
339 | new_cnt = old_cnt + add_cnt + 1; | ||
340 | groups = devm_kcalloc(&rtc->dev, new_cnt, sizeof(*groups), GFP_KERNEL); | ||
341 | if (IS_ERR_OR_NULL(groups)) | ||
342 | return PTR_ERR(groups); | ||
343 | memcpy(groups, rtc->dev.groups, old_cnt * sizeof(*groups)); | ||
344 | memcpy(groups + old_cnt, grps, add_cnt * sizeof(*groups)); | ||
345 | groups[old_cnt + add_cnt] = NULL; | ||
346 | |||
347 | old = rtc->dev.groups; | ||
348 | rtc->dev.groups = groups; | ||
349 | if (old && old != rtc_attr_groups) | ||
350 | devm_kfree(&rtc->dev, old); | ||
351 | |||
352 | return 0; | ||
353 | } | ||
354 | EXPORT_SYMBOL(rtc_add_groups); | ||
355 | |||
356 | int rtc_add_group(struct rtc_device *rtc, const struct attribute_group *grp) | ||
357 | { | ||
358 | const struct attribute_group *groups[] = { grp, NULL }; | ||
359 | |||
360 | return rtc_add_groups(rtc, groups); | ||
361 | } | ||
362 | EXPORT_SYMBOL(rtc_add_group); | ||
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c index 8469256edc2a..ade6a82709be 100644 --- a/drivers/rtc/rtc-test.c +++ b/drivers/rtc/rtc-test.c | |||
@@ -22,7 +22,7 @@ struct rtc_test_data { | |||
22 | bool alarm_en; | 22 | bool alarm_en; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | struct platform_device *pdev[MAX_RTC_TEST]; | 25 | static struct platform_device *pdev[MAX_RTC_TEST]; |
26 | 26 | ||
27 | static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 27 | static int test_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
28 | { | 28 | { |
diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 6268208760e9..6aedc30003e7 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h | |||
@@ -87,16 +87,11 @@ struct rtc_class_ops { | |||
87 | int (*set_offset)(struct device *, long offset); | 87 | int (*set_offset)(struct device *, long offset); |
88 | }; | 88 | }; |
89 | 89 | ||
90 | typedef struct rtc_task { | ||
91 | void (*func)(void *private_data); | ||
92 | void *private_data; | ||
93 | } rtc_task_t; | ||
94 | |||
95 | |||
96 | struct rtc_timer { | 90 | struct rtc_timer { |
97 | struct rtc_task task; | ||
98 | struct timerqueue_node node; | 91 | struct timerqueue_node node; |
99 | ktime_t period; | 92 | ktime_t period; |
93 | void (*func)(void *private_data); | ||
94 | void *private_data; | ||
100 | int enabled; | 95 | int enabled; |
101 | }; | 96 | }; |
102 | 97 | ||
@@ -121,8 +116,6 @@ struct rtc_device { | |||
121 | wait_queue_head_t irq_queue; | 116 | wait_queue_head_t irq_queue; |
122 | struct fasync_struct *async_queue; | 117 | struct fasync_struct *async_queue; |
123 | 118 | ||
124 | struct rtc_task *irq_task; | ||
125 | spinlock_t irq_task_lock; | ||
126 | int irq_freq; | 119 | int irq_freq; |
127 | int max_user_freq; | 120 | int max_user_freq; |
128 | 121 | ||
@@ -204,14 +197,8 @@ extern void rtc_update_irq(struct rtc_device *rtc, | |||
204 | extern struct rtc_device *rtc_class_open(const char *name); | 197 | extern struct rtc_device *rtc_class_open(const char *name); |
205 | extern void rtc_class_close(struct rtc_device *rtc); | 198 | extern void rtc_class_close(struct rtc_device *rtc); |
206 | 199 | ||
207 | extern int rtc_irq_register(struct rtc_device *rtc, | 200 | extern int rtc_irq_set_state(struct rtc_device *rtc, int enabled); |
208 | struct rtc_task *task); | 201 | extern int rtc_irq_set_freq(struct rtc_device *rtc, int freq); |
209 | extern void rtc_irq_unregister(struct rtc_device *rtc, | ||
210 | struct rtc_task *task); | ||
211 | extern int rtc_irq_set_state(struct rtc_device *rtc, | ||
212 | struct rtc_task *task, int enabled); | ||
213 | extern int rtc_irq_set_freq(struct rtc_device *rtc, | ||
214 | struct rtc_task *task, int freq); | ||
215 | extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled); | 202 | extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled); |
216 | extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); | 203 | extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); |
217 | extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, | 204 | extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, |