diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-02 17:19:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-02 17:19:19 -0500 |
commit | bf644990a796bd72d6f3977f3307169919a23f85 (patch) | |
tree | 812913216ec1ff6c8223169a743cbf0a0504291a | |
parent | b89e32ccd1be92a3643df3908d3026b09e271616 (diff) | |
parent | 4402be2b4ca7f53b6213a9e6b3abe9cdcc683e9b (diff) |
Merge tag 'rtc-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
Pull RTC updates from Alexandre Belloni:
"Not much this cycle. I've pushed the at32ap700x removal late but it is
unlikely to cause any issues.
Summary:
Subsystem:
- Move ABI documentation to Documentation/ABI
New driver:
- NXP i.MX53 SRTC
- Chrome OS EC RTC
Drivers:
- Remove at32ap700x
- Many fixes in various error paths"
* tag 'rtc-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux:
rtc: remove rtc-at32ap700x
Documentation: rtc: move iotcl interface documentation to ABI
Documentation: rtc: add sysfs file permissions
Documentation: rtc: move sysfs documentation to ABI
rtc: mxc_v2: remove __exit annotation
rtc: mxc_v2: Remove unnecessary platform_get_resource() error check
rtc: add mxc driver for i.MX53 SRTC
dt-bindings: rtc: add bindings for i.MX53 SRTC
rtc: r7301: Fix a possible sleep-in-atomic bug in rtc7301_set_time
rtc: r7301: Fix a possible sleep-in-atomic bug in rtc7301_read_time
rtc: omap: fix unbalanced clk_prepare_enable/clk_disable_unprepare
rtc: ac100: Fix multiple race conditions
rtc: sun6i: ensure rtc is kfree'd on error
rtc: cros-ec: add cros-ec-rtc driver.
mfd: cros_ec: Introduce RTC commands and events definitions.
rtc: stm32: Fix copyright
rtc: Remove unused RTC_DEVICE_NAME_SIZE
rtc: r9701: Remove r9701_remove function
rtc: brcmstb-waketimer: fix error handling in brcmstb_waketmr_probe()
-rw-r--r-- | Documentation/ABI/testing/rtc-cdev | 42 | ||||
-rw-r--r-- | Documentation/ABI/testing/sysfs-class-rtc | 91 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt | 17 | ||||
-rw-r--r-- | Documentation/rtc.txt | 81 | ||||
-rw-r--r-- | drivers/rtc/Kconfig | 27 | ||||
-rw-r--r-- | drivers/rtc/Makefile | 3 | ||||
-rw-r--r-- | drivers/rtc/rtc-ac100.c | 19 | ||||
-rw-r--r-- | drivers/rtc/rtc-at32ap700x.c | 287 | ||||
-rw-r--r-- | drivers/rtc/rtc-brcmstb-waketimer.c | 15 | ||||
-rw-r--r-- | drivers/rtc/rtc-cros-ec.c | 413 | ||||
-rw-r--r-- | drivers/rtc/rtc-mxc_v2.c | 419 | ||||
-rw-r--r-- | drivers/rtc/rtc-omap.c | 5 | ||||
-rw-r--r-- | drivers/rtc/rtc-r7301.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-r9701.c | 6 | ||||
-rw-r--r-- | drivers/rtc/rtc-stm32.c | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-sun6i.c | 4 | ||||
-rw-r--r-- | include/linux/mfd/cros_ec_commands.h | 8 | ||||
-rw-r--r-- | include/linux/rtc.h | 1 |
18 files changed, 1049 insertions, 397 deletions
diff --git a/Documentation/ABI/testing/rtc-cdev b/Documentation/ABI/testing/rtc-cdev new file mode 100644 index 000000000000..97447283f13b --- /dev/null +++ b/Documentation/ABI/testing/rtc-cdev | |||
@@ -0,0 +1,42 @@ | |||
1 | What: /dev/rtcX | ||
2 | Date: April 2005 | ||
3 | KernelVersion: 2.6.12 | ||
4 | Contact: linux-rtc@vger.kernel.org | ||
5 | Description: | ||
6 | The ioctl interface to drivers for real-time clocks (RTCs). | ||
7 | Following actions are supported: | ||
8 | |||
9 | * RTC_RD_TIME, RTC_SET_TIME: Read or set the RTC time. Time | ||
10 | format is a Gregorian calendar date and 24 hour wall clock | ||
11 | time. | ||
12 | |||
13 | * RTC_AIE_ON, RTC_AIE_OFF: Enable or disable the alarm interrupt | ||
14 | for RTCs that support alarms | ||
15 | |||
16 | * RTC_ALM_READ, RTC_ALM_SET: Read or set the alarm time for | ||
17 | RTCs that support alarms. Can be set upto 24 hours in the | ||
18 | future. Requires a separate RTC_AIE_ON call to enable the | ||
19 | alarm interrupt. (Prefer to use RTC_WKALM_*) | ||
20 | |||
21 | * RTC_WKALM_RD, RTC_WKALM_SET: For RTCs that support a more | ||
22 | powerful interface, which can issue alarms beyond 24 hours and | ||
23 | enable IRQs in the same request. | ||
24 | |||
25 | * RTC_PIE_ON, RTC_PIE_OFF: Enable or disable the periodic | ||
26 | interrupt for RTCs that support periodic interrupts. | ||
27 | |||
28 | * RTC_UIE_ON, RTC_UIE_OFF: Enable or disable the update | ||
29 | interrupt for RTCs that support it. | ||
30 | |||
31 | * RTC_IRQP_READ, RTC_IRQP_SET: Read or set the frequency for | ||
32 | periodic interrupts for RTCs that support periodic interrupts. | ||
33 | Requires a separate RTC_PIE_ON call to enable the periodic | ||
34 | interrupts. | ||
35 | |||
36 | The ioctl() calls supported by the older /dev/rtc interface are | ||
37 | also supported by the newer RTC class framework. However, | ||
38 | because the chips and systems are not standardized, some PC/AT | ||
39 | functionality might not be provided. And in the same way, some | ||
40 | newer features -- including those enabled by ACPI -- are exposed | ||
41 | by the RTC class framework, but can't be supported by the older | ||
42 | driver. | ||
diff --git a/Documentation/ABI/testing/sysfs-class-rtc b/Documentation/ABI/testing/sysfs-class-rtc new file mode 100644 index 000000000000..cf60412882f0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-rtc | |||
@@ -0,0 +1,91 @@ | |||
1 | What: /sys/class/rtc/ | ||
2 | Date: March 2006 | ||
3 | KernelVersion: 2.6.17 | ||
4 | Contact: linux-rtc@vger.kernel.org | ||
5 | Description: | ||
6 | The rtc/ class subdirectory belongs to the RTC subsystem. | ||
7 | |||
8 | What: /sys/class/rtc/rtcX/ | ||
9 | Date: March 2006 | ||
10 | KernelVersion: 2.6.17 | ||
11 | Contact: linux-rtc@vger.kernel.org | ||
12 | Description: | ||
13 | The /sys/class/rtc/rtc{0,1,2,3,...} directories correspond | ||
14 | to each RTC device. | ||
15 | |||
16 | What: /sys/class/rtc/rtcX/date | ||
17 | Date: March 2006 | ||
18 | KernelVersion: 2.6.17 | ||
19 | Contact: linux-rtc@vger.kernel.org | ||
20 | Description: | ||
21 | (RO) RTC-provided date in YYYY-MM-DD format | ||
22 | |||
23 | What: /sys/class/rtc/rtcX/hctosys | ||
24 | Date: September 2009 | ||
25 | KernelVersion: 2.6.32 | ||
26 | Contact: linux-rtc@vger.kernel.org | ||
27 | Description: | ||
28 | (RO) 1 if the RTC provided the system time at boot via the | ||
29 | CONFIG_RTC_HCTOSYS kernel option, 0 otherwise | ||
30 | |||
31 | What: /sys/class/rtc/rtcX/max_user_freq | ||
32 | Date: October 2007 | ||
33 | KernelVersion: 2.6.24 | ||
34 | Contact: linux-rtc@vger.kernel.org | ||
35 | Description: | ||
36 | (RW) The maximum interrupt rate an unprivileged user may request | ||
37 | from this RTC. | ||
38 | |||
39 | What: /sys/class/rtc/rtcX/name | ||
40 | Date: March 2006 | ||
41 | KernelVersion: 2.6.17 | ||
42 | Contact: linux-rtc@vger.kernel.org | ||
43 | Description: | ||
44 | (RO) The name of the RTC corresponding to this sysfs directory | ||
45 | |||
46 | What: /sys/class/rtc/rtcX/since_epoch | ||
47 | Date: March 2006 | ||
48 | KernelVersion: 2.6.17 | ||
49 | Contact: linux-rtc@vger.kernel.org | ||
50 | Description: | ||
51 | (RO) RTC-provided time as the number of seconds since the epoch | ||
52 | |||
53 | What: /sys/class/rtc/rtcX/time | ||
54 | Date: March 2006 | ||
55 | KernelVersion: 2.6.17 | ||
56 | Contact: linux-rtc@vger.kernel.org | ||
57 | Description: | ||
58 | (RO) RTC-provided time in 24-hour notation (hh:mm:ss) | ||
59 | |||
60 | What: /sys/class/rtc/rtcX/*/nvmem | ||
61 | Date: February 2016 | ||
62 | KernelVersion: 4.6 | ||
63 | Contact: linux-rtc@vger.kernel.org | ||
64 | Description: | ||
65 | (RW) The non volatile storage exported as a raw file, as | ||
66 | described in Documentation/nvmem/nvmem.txt | ||
67 | |||
68 | What: /sys/class/rtc/rtcX/offset | ||
69 | Date: February 2016 | ||
70 | KernelVersion: 4.6 | ||
71 | Contact: linux-rtc@vger.kernel.org | ||
72 | Description: | ||
73 | (RW) The amount which the rtc clock has been adjusted in | ||
74 | firmware. Visible only if the driver supports clock offset | ||
75 | adjustment. The unit is parts per billion, i.e. The number of | ||
76 | clock ticks which are added to or removed from the rtc's base | ||
77 | clock per billion ticks. A positive value makes a day pass more | ||
78 | slowly, longer, and a negative value makes a day pass more | ||
79 | quickly. | ||
80 | |||
81 | What: /sys/class/rtc/rtcX/wakealarm | ||
82 | Date: February 2007 | ||
83 | KernelVersion: 2.6.20 | ||
84 | Contact: linux-rtc@vger.kernel.org | ||
85 | Description: | ||
86 | (RW) The time at which the clock will generate a system wakeup | ||
87 | event. This is a one shot wakeup event, so must be reset after | ||
88 | wake if a daily wakeup is required. Format is seconds since the | ||
89 | epoch by default, or if there's a leading +, seconds in the | ||
90 | future, or if there is a leading +=, seconds ahead of the | ||
91 | current alarm. | ||
diff --git a/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt b/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt new file mode 100644 index 000000000000..79d7e87b0d91 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-mxc_v2.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | * i.MX53 Secure Real Time Clock (SRTC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be: "fsl,imx53-rtc" | ||
5 | - reg: physical base address of the controller and length of memory mapped | ||
6 | region. | ||
7 | - clocks: should contain the phandle for the rtc clock | ||
8 | - interrupts: rtc alarm interrupt | ||
9 | |||
10 | Example: | ||
11 | |||
12 | rtc@53fa4000 { | ||
13 | compatible = "fsl,imx53-rtc"; | ||
14 | reg = <0x53fa4000 0x4000>; | ||
15 | interrupts = <24>; | ||
16 | clocks = <&clks IMX5_CLK_SRTC_GATE>; | ||
17 | }; | ||
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt index c0c977445fb9..a129acf38537 100644 --- a/Documentation/rtc.txt +++ b/Documentation/rtc.txt | |||
@@ -136,82 +136,5 @@ a high functionality RTC is integrated into the SOC. That system might read | |||
136 | the system clock from the discrete RTC, but use the integrated one for all | 136 | the system clock from the discrete RTC, but use the integrated one for all |
137 | other tasks, because of its greater functionality. | 137 | other tasks, because of its greater functionality. |
138 | 138 | ||
139 | SYSFS interface | 139 | Check out tools/testing/selftests/timers/rtctest.c for an example usage of the |
140 | --------------- | 140 | ioctl interface. |
141 | |||
142 | The sysfs interface under /sys/class/rtc/rtcN provides access to various | ||
143 | rtc attributes without requiring the use of ioctls. All dates and times | ||
144 | are in the RTC's timezone, rather than in system time. | ||
145 | |||
146 | ================ ============================================================== | ||
147 | date RTC-provided date | ||
148 | hctosys 1 if the RTC provided the system time at boot via the | ||
149 | CONFIG_RTC_HCTOSYS kernel option, 0 otherwise | ||
150 | max_user_freq The maximum interrupt rate an unprivileged user may request | ||
151 | from this RTC. | ||
152 | name The name of the RTC corresponding to this sysfs directory | ||
153 | since_epoch The number of seconds since the epoch according to the RTC | ||
154 | time RTC-provided time | ||
155 | wakealarm The time at which the clock will generate a system wakeup | ||
156 | event. This is a one shot wakeup event, so must be reset | ||
157 | after wake if a daily wakeup is required. Format is seconds | ||
158 | since the epoch by default, or if there's a leading +, seconds | ||
159 | in the future, or if there is a leading +=, seconds ahead of | ||
160 | the current alarm. | ||
161 | offset The amount which the rtc clock has been adjusted in firmware. | ||
162 | Visible only if the driver supports clock offset adjustment. | ||
163 | The unit is parts per billion, i.e. The number of clock ticks | ||
164 | which are added to or removed from the rtc's base clock per | ||
165 | billion ticks. A positive value makes a day pass more slowly, | ||
166 | longer, and a negative value makes a day pass more quickly. | ||
167 | */nvmem The non volatile storage exported as a raw file, as described | ||
168 | in Documentation/nvmem/nvmem.txt | ||
169 | ================ ============================================================== | ||
170 | |||
171 | IOCTL interface | ||
172 | --------------- | ||
173 | |||
174 | The ioctl() calls supported by /dev/rtc are also supported by the RTC class | ||
175 | framework. However, because the chips and systems are not standardized, | ||
176 | some PC/AT functionality might not be provided. And in the same way, some | ||
177 | newer features -- including those enabled by ACPI -- are exposed by the | ||
178 | RTC class framework, but can't be supported by the older driver. | ||
179 | |||
180 | * RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading | ||
181 | time, returning the result as a Gregorian calendar date and 24 hour | ||
182 | wall clock time. To be most useful, this time may also be updated. | ||
183 | |||
184 | * RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC | ||
185 | is connected to an IRQ line, it can often issue an alarm IRQ up to | ||
186 | 24 hours in the future. (Use RTC_WKALM_* by preference.) | ||
187 | |||
188 | * RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond | ||
189 | the next 24 hours use a slightly more powerful API, which supports | ||
190 | setting the longer alarm time and enabling its IRQ using a single | ||
191 | request (using the same model as EFI firmware). | ||
192 | |||
193 | * RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, the RTC framework | ||
194 | will emulate this mechanism. | ||
195 | |||
196 | * RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... these icotls | ||
197 | are emulated via a kernel hrtimer. | ||
198 | |||
199 | In many cases, the RTC alarm can be a system wake event, used to force | ||
200 | Linux out of a low power sleep state (or hibernation) back to a fully | ||
201 | operational state. For example, a system could enter a deep power saving | ||
202 | state until it's time to execute some scheduled tasks. | ||
203 | |||
204 | Note that many of these ioctls are handled by the common rtc-dev interface. | ||
205 | Some common examples: | ||
206 | |||
207 | * RTC_RD_TIME, RTC_SET_TIME: the read_time/set_time functions will be | ||
208 | called with appropriate values. | ||
209 | |||
210 | * RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: gets or sets | ||
211 | the alarm rtc_timer. May call the set_alarm driver function. | ||
212 | |||
213 | * RTC_IRQP_SET, RTC_IRQP_READ: These are emulated by the generic code. | ||
214 | |||
215 | * RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code. | ||
216 | |||
217 | If all else fails, check out the tools/testing/selftests/timers/rtctest.c test! | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b59a31b079a5..8ab5f0a5d323 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -1255,6 +1255,16 @@ config RTC_DRV_ZYNQMP | |||
1255 | If you say yes here you get support for the RTC controller found on | 1255 | If you say yes here you get support for the RTC controller found on |
1256 | Xilinx Zynq Ultrascale+ MPSoC. | 1256 | Xilinx Zynq Ultrascale+ MPSoC. |
1257 | 1257 | ||
1258 | config RTC_DRV_CROS_EC | ||
1259 | tristate "Chrome OS EC RTC driver" | ||
1260 | depends on MFD_CROS_EC | ||
1261 | help | ||
1262 | If you say yes here you will get support for the | ||
1263 | Chrome OS Embedded Controller's RTC. | ||
1264 | |||
1265 | This driver can also be built as a module. If so, the module | ||
1266 | will be called rtc-cros-ec. | ||
1267 | |||
1258 | comment "on-CPU RTC drivers" | 1268 | comment "on-CPU RTC drivers" |
1259 | 1269 | ||
1260 | config RTC_DRV_ASM9260 | 1270 | config RTC_DRV_ASM9260 |
@@ -1392,13 +1402,6 @@ config RTC_DRV_PL031 | |||
1392 | To compile this driver as a module, choose M here: the | 1402 | To compile this driver as a module, choose M here: the |
1393 | module will be called rtc-pl031. | 1403 | module will be called rtc-pl031. |
1394 | 1404 | ||
1395 | config RTC_DRV_AT32AP700X | ||
1396 | tristate "AT32AP700X series RTC" | ||
1397 | depends on PLATFORM_AT32AP || COMPILE_TEST | ||
1398 | help | ||
1399 | Driver for the internal RTC (Realtime Clock) on Atmel AVR32 | ||
1400 | AT32AP700x family processors. | ||
1401 | |||
1402 | config RTC_DRV_AT91RM9200 | 1405 | config RTC_DRV_AT91RM9200 |
1403 | tristate "AT91RM9200 or some AT91SAM9 RTC" | 1406 | tristate "AT91RM9200 or some AT91SAM9 RTC" |
1404 | depends on ARCH_AT91 || COMPILE_TEST | 1407 | depends on ARCH_AT91 || COMPILE_TEST |
@@ -1689,6 +1692,16 @@ config RTC_DRV_MXC | |||
1689 | This driver can also be built as a module, if so, the module | 1692 | This driver can also be built as a module, if so, the module |
1690 | will be called "rtc-mxc". | 1693 | will be called "rtc-mxc". |
1691 | 1694 | ||
1695 | config RTC_DRV_MXC_V2 | ||
1696 | tristate "Freescale MXC Real Time Clock for i.MX53" | ||
1697 | depends on ARCH_MXC | ||
1698 | help | ||
1699 | If you say yes here you get support for the Freescale MXC | ||
1700 | SRTC module in i.MX53 processor. | ||
1701 | |||
1702 | This driver can also be built as a module, if so, the module | ||
1703 | will be called "rtc-mxc_v2". | ||
1704 | |||
1692 | config RTC_DRV_SNVS | 1705 | config RTC_DRV_SNVS |
1693 | tristate "Freescale SNVS RTC support" | 1706 | tristate "Freescale SNVS RTC support" |
1694 | select REGMAP_MMIO | 1707 | select REGMAP_MMIO |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f2f50c11dc38..4fbf87e45a7c 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -33,7 +33,6 @@ obj-$(CONFIG_RTC_DRV_AC100) += rtc-ac100.o | |||
33 | obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o | 33 | obj-$(CONFIG_RTC_DRV_ARMADA38X) += rtc-armada38x.o |
34 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o | 34 | obj-$(CONFIG_RTC_DRV_AS3722) += rtc-as3722.o |
35 | obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o | 35 | obj-$(CONFIG_RTC_DRV_ASM9260) += rtc-asm9260.o |
36 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | ||
37 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 36 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
38 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | 37 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o |
39 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o | 38 | obj-$(CONFIG_RTC_DRV_AU1XXX) += rtc-au1xxx.o |
@@ -44,6 +43,7 @@ obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | |||
44 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 43 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
45 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o | 44 | obj-$(CONFIG_RTC_DRV_COH901331) += rtc-coh901331.o |
46 | obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o | 45 | obj-$(CONFIG_RTC_DRV_CPCAP) += rtc-cpcap.o |
46 | obj-$(CONFIG_RTC_DRV_CROS_EC) += rtc-cros-ec.o | ||
47 | obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o | 47 | obj-$(CONFIG_RTC_DRV_DA9052) += rtc-da9052.o |
48 | obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o | 48 | obj-$(CONFIG_RTC_DRV_DA9055) += rtc-da9055.o |
49 | obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o | 49 | obj-$(CONFIG_RTC_DRV_DA9063) += rtc-da9063.o |
@@ -106,6 +106,7 @@ obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o | |||
106 | obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o | 106 | obj-$(CONFIG_RTC_DRV_MT7622) += rtc-mt7622.o |
107 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o | 107 | obj-$(CONFIG_RTC_DRV_MV) += rtc-mv.o |
108 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o | 108 | obj-$(CONFIG_RTC_DRV_MXC) += rtc-mxc.o |
109 | obj-$(CONFIG_RTC_DRV_MXC_V2) += rtc-mxc_v2.o | ||
109 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o | 110 | obj-$(CONFIG_RTC_DRV_NUC900) += rtc-nuc900.o |
110 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | 111 | obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o |
111 | obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o | 112 | obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o |
diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 0282ccc6181c..8ff9dc3fe5bf 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c | |||
@@ -569,6 +569,12 @@ static int ac100_rtc_probe(struct platform_device *pdev) | |||
569 | return chip->irq; | 569 | return chip->irq; |
570 | } | 570 | } |
571 | 571 | ||
572 | chip->rtc = devm_rtc_allocate_device(&pdev->dev); | ||
573 | if (IS_ERR(chip->rtc)) | ||
574 | return PTR_ERR(chip->rtc); | ||
575 | |||
576 | chip->rtc->ops = &ac100_rtc_ops; | ||
577 | |||
572 | ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, | 578 | ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, |
573 | ac100_rtc_irq, | 579 | ac100_rtc_irq, |
574 | IRQF_SHARED | IRQF_ONESHOT, | 580 | IRQF_SHARED | IRQF_ONESHOT, |
@@ -588,17 +594,16 @@ static int ac100_rtc_probe(struct platform_device *pdev) | |||
588 | /* clear counter alarm pending interrupts */ | 594 | /* clear counter alarm pending interrupts */ |
589 | regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE); | 595 | regmap_write(chip->regmap, AC100_ALM_INT_STA, AC100_ALM_INT_ENABLE); |
590 | 596 | ||
591 | chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-ac100", | ||
592 | &ac100_rtc_ops, THIS_MODULE); | ||
593 | if (IS_ERR(chip->rtc)) { | ||
594 | dev_err(&pdev->dev, "unable to register device\n"); | ||
595 | return PTR_ERR(chip->rtc); | ||
596 | } | ||
597 | |||
598 | ret = ac100_rtc_register_clks(chip); | 597 | ret = ac100_rtc_register_clks(chip); |
599 | if (ret) | 598 | if (ret) |
600 | return ret; | 599 | return ret; |
601 | 600 | ||
601 | ret = rtc_register_device(chip->rtc); | ||
602 | if (ret) { | ||
603 | dev_err(&pdev->dev, "unable to register device\n"); | ||
604 | return ret; | ||
605 | } | ||
606 | |||
602 | dev_info(&pdev->dev, "RTC enabled\n"); | 607 | dev_info(&pdev->dev, "RTC enabled\n"); |
603 | 608 | ||
604 | return 0; | 609 | return 0; |
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c deleted file mode 100644 index de8bf56a41e7..000000000000 --- a/drivers/rtc/rtc-at32ap700x.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /* | ||
2 | * An RTC driver for the AVR32 AT32AP700x processor series. | ||
3 | * | ||
4 | * Copyright (C) 2007 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/rtc.h> | ||
16 | #include <linux/io.h> | ||
17 | |||
18 | /* | ||
19 | * This is a bare-bones RTC. It runs during most system sleep states, but has | ||
20 | * no battery backup and gets reset during system restart. It must be | ||
21 | * initialized from an external clock (network, I2C, etc) before it can be of | ||
22 | * much use. | ||
23 | * | ||
24 | * The alarm functionality is limited by the hardware, not supporting | ||
25 | * periodic interrupts. | ||
26 | */ | ||
27 | |||
28 | #define RTC_CTRL 0x00 | ||
29 | #define RTC_CTRL_EN 0 | ||
30 | #define RTC_CTRL_PCLR 1 | ||
31 | #define RTC_CTRL_TOPEN 2 | ||
32 | #define RTC_CTRL_PSEL 8 | ||
33 | |||
34 | #define RTC_VAL 0x04 | ||
35 | |||
36 | #define RTC_TOP 0x08 | ||
37 | |||
38 | #define RTC_IER 0x10 | ||
39 | #define RTC_IER_TOPI 0 | ||
40 | |||
41 | #define RTC_IDR 0x14 | ||
42 | #define RTC_IDR_TOPI 0 | ||
43 | |||
44 | #define RTC_IMR 0x18 | ||
45 | #define RTC_IMR_TOPI 0 | ||
46 | |||
47 | #define RTC_ISR 0x1c | ||
48 | #define RTC_ISR_TOPI 0 | ||
49 | |||
50 | #define RTC_ICR 0x20 | ||
51 | #define RTC_ICR_TOPI 0 | ||
52 | |||
53 | #define RTC_BIT(name) (1 << RTC_##name) | ||
54 | #define RTC_BF(name, value) ((value) << RTC_##name) | ||
55 | |||
56 | #define rtc_readl(dev, reg) \ | ||
57 | __raw_readl((dev)->regs + RTC_##reg) | ||
58 | #define rtc_writel(dev, reg, value) \ | ||
59 | __raw_writel((value), (dev)->regs + RTC_##reg) | ||
60 | |||
61 | struct rtc_at32ap700x { | ||
62 | struct rtc_device *rtc; | ||
63 | void __iomem *regs; | ||
64 | unsigned long alarm_time; | ||
65 | unsigned long irq; | ||
66 | /* Protect against concurrent register access. */ | ||
67 | spinlock_t lock; | ||
68 | }; | ||
69 | |||
70 | static int at32_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
71 | { | ||
72 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | ||
73 | unsigned long now; | ||
74 | |||
75 | now = rtc_readl(rtc, VAL); | ||
76 | rtc_time_to_tm(now, tm); | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | static int at32_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
82 | { | ||
83 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | ||
84 | unsigned long now; | ||
85 | int ret; | ||
86 | |||
87 | ret = rtc_tm_to_time(tm, &now); | ||
88 | if (ret == 0) | ||
89 | rtc_writel(rtc, VAL, now); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
95 | { | ||
96 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | ||
97 | |||
98 | spin_lock_irq(&rtc->lock); | ||
99 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); | ||
100 | alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; | ||
101 | alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0; | ||
102 | spin_unlock_irq(&rtc->lock); | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
108 | { | ||
109 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | ||
110 | unsigned long rtc_unix_time; | ||
111 | unsigned long alarm_unix_time; | ||
112 | int ret; | ||
113 | |||
114 | rtc_unix_time = rtc_readl(rtc, VAL); | ||
115 | |||
116 | ret = rtc_tm_to_time(&alrm->time, &alarm_unix_time); | ||
117 | if (ret) | ||
118 | return ret; | ||
119 | |||
120 | if (alarm_unix_time < rtc_unix_time) | ||
121 | return -EINVAL; | ||
122 | |||
123 | spin_lock_irq(&rtc->lock); | ||
124 | rtc->alarm_time = alarm_unix_time; | ||
125 | rtc_writel(rtc, TOP, rtc->alarm_time); | ||
126 | if (alrm->enabled) | ||
127 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | ||
128 | | RTC_BIT(CTRL_TOPEN)); | ||
129 | else | ||
130 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | ||
131 | & ~RTC_BIT(CTRL_TOPEN)); | ||
132 | spin_unlock_irq(&rtc->lock); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static int at32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | ||
138 | { | ||
139 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | ||
140 | int ret = 0; | ||
141 | |||
142 | spin_lock_irq(&rtc->lock); | ||
143 | |||
144 | if (enabled) { | ||
145 | if (rtc_readl(rtc, VAL) > rtc->alarm_time) { | ||
146 | ret = -EINVAL; | ||
147 | goto out; | ||
148 | } | ||
149 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | ||
150 | | RTC_BIT(CTRL_TOPEN)); | ||
151 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); | ||
152 | rtc_writel(rtc, IER, RTC_BIT(IER_TOPI)); | ||
153 | } else { | ||
154 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | ||
155 | & ~RTC_BIT(CTRL_TOPEN)); | ||
156 | rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); | ||
157 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); | ||
158 | } | ||
159 | out: | ||
160 | spin_unlock_irq(&rtc->lock); | ||
161 | |||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static irqreturn_t at32_rtc_interrupt(int irq, void *dev_id) | ||
166 | { | ||
167 | struct rtc_at32ap700x *rtc = (struct rtc_at32ap700x *)dev_id; | ||
168 | unsigned long isr = rtc_readl(rtc, ISR); | ||
169 | unsigned long events = 0; | ||
170 | int ret = IRQ_NONE; | ||
171 | |||
172 | spin_lock(&rtc->lock); | ||
173 | |||
174 | if (isr & RTC_BIT(ISR_TOPI)) { | ||
175 | rtc_writel(rtc, ICR, RTC_BIT(ICR_TOPI)); | ||
176 | rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); | ||
177 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | ||
178 | & ~RTC_BIT(CTRL_TOPEN)); | ||
179 | rtc_writel(rtc, VAL, rtc->alarm_time); | ||
180 | events = RTC_AF | RTC_IRQF; | ||
181 | rtc_update_irq(rtc->rtc, 1, events); | ||
182 | ret = IRQ_HANDLED; | ||
183 | } | ||
184 | |||
185 | spin_unlock(&rtc->lock); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static const struct rtc_class_ops at32_rtc_ops = { | ||
191 | .read_time = at32_rtc_readtime, | ||
192 | .set_time = at32_rtc_settime, | ||
193 | .read_alarm = at32_rtc_readalarm, | ||
194 | .set_alarm = at32_rtc_setalarm, | ||
195 | .alarm_irq_enable = at32_rtc_alarm_irq_enable, | ||
196 | }; | ||
197 | |||
198 | static int __init at32_rtc_probe(struct platform_device *pdev) | ||
199 | { | ||
200 | struct resource *regs; | ||
201 | struct rtc_at32ap700x *rtc; | ||
202 | int irq; | ||
203 | int ret; | ||
204 | |||
205 | rtc = devm_kzalloc(&pdev->dev, sizeof(struct rtc_at32ap700x), | ||
206 | GFP_KERNEL); | ||
207 | if (!rtc) | ||
208 | return -ENOMEM; | ||
209 | |||
210 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
211 | if (!regs) { | ||
212 | dev_dbg(&pdev->dev, "no mmio resource defined\n"); | ||
213 | return -ENXIO; | ||
214 | } | ||
215 | |||
216 | irq = platform_get_irq(pdev, 0); | ||
217 | if (irq <= 0) { | ||
218 | dev_dbg(&pdev->dev, "could not get irq\n"); | ||
219 | return -ENXIO; | ||
220 | } | ||
221 | |||
222 | rtc->irq = irq; | ||
223 | rtc->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); | ||
224 | if (!rtc->regs) { | ||
225 | dev_dbg(&pdev->dev, "could not map I/O memory\n"); | ||
226 | return -ENOMEM; | ||
227 | } | ||
228 | spin_lock_init(&rtc->lock); | ||
229 | |||
230 | /* | ||
231 | * Maybe init RTC: count from zero at 1 Hz, disable wrap irq. | ||
232 | * | ||
233 | * Do not reset VAL register, as it can hold an old time | ||
234 | * from last JTAG reset. | ||
235 | */ | ||
236 | if (!(rtc_readl(rtc, CTRL) & RTC_BIT(CTRL_EN))) { | ||
237 | rtc_writel(rtc, CTRL, RTC_BIT(CTRL_PCLR)); | ||
238 | rtc_writel(rtc, IDR, RTC_BIT(IDR_TOPI)); | ||
239 | rtc_writel(rtc, CTRL, RTC_BF(CTRL_PSEL, 0xe) | ||
240 | | RTC_BIT(CTRL_EN)); | ||
241 | } | ||
242 | |||
243 | ret = devm_request_irq(&pdev->dev, irq, at32_rtc_interrupt, IRQF_SHARED, | ||
244 | "rtc", rtc); | ||
245 | if (ret) { | ||
246 | dev_dbg(&pdev->dev, "could not request irq %d\n", irq); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | platform_set_drvdata(pdev, rtc); | ||
251 | |||
252 | rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, | ||
253 | &at32_rtc_ops, THIS_MODULE); | ||
254 | if (IS_ERR(rtc->rtc)) { | ||
255 | dev_dbg(&pdev->dev, "could not register rtc device\n"); | ||
256 | return PTR_ERR(rtc->rtc); | ||
257 | } | ||
258 | |||
259 | device_init_wakeup(&pdev->dev, 1); | ||
260 | |||
261 | dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n", | ||
262 | (unsigned long)rtc->regs, rtc->irq); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int __exit at32_rtc_remove(struct platform_device *pdev) | ||
268 | { | ||
269 | device_init_wakeup(&pdev->dev, 0); | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | MODULE_ALIAS("platform:at32ap700x_rtc"); | ||
275 | |||
276 | static struct platform_driver at32_rtc_driver = { | ||
277 | .remove = __exit_p(at32_rtc_remove), | ||
278 | .driver = { | ||
279 | .name = "at32ap700x_rtc", | ||
280 | }, | ||
281 | }; | ||
282 | |||
283 | module_platform_driver_probe(at32_rtc_driver, at32_rtc_probe); | ||
284 | |||
285 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); | ||
286 | MODULE_DESCRIPTION("Real time clock for AVR32 AT32AP700x"); | ||
287 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-brcmstb-waketimer.c b/drivers/rtc/rtc-brcmstb-waketimer.c index 796ac792a381..6cee61201c30 100644 --- a/drivers/rtc/rtc-brcmstb-waketimer.c +++ b/drivers/rtc/rtc-brcmstb-waketimer.c | |||
@@ -253,7 +253,7 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) | |||
253 | ret = devm_request_irq(dev, timer->irq, brcmstb_waketmr_irq, 0, | 253 | ret = devm_request_irq(dev, timer->irq, brcmstb_waketmr_irq, 0, |
254 | "brcmstb-waketimer", timer); | 254 | "brcmstb-waketimer", timer); |
255 | if (ret < 0) | 255 | if (ret < 0) |
256 | return ret; | 256 | goto err_clk; |
257 | 257 | ||
258 | timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; | 258 | timer->reboot_notifier.notifier_call = brcmstb_waketmr_reboot; |
259 | register_reboot_notifier(&timer->reboot_notifier); | 259 | register_reboot_notifier(&timer->reboot_notifier); |
@@ -262,12 +262,21 @@ static int brcmstb_waketmr_probe(struct platform_device *pdev) | |||
262 | &brcmstb_waketmr_ops, THIS_MODULE); | 262 | &brcmstb_waketmr_ops, THIS_MODULE); |
263 | if (IS_ERR(timer->rtc)) { | 263 | if (IS_ERR(timer->rtc)) { |
264 | dev_err(dev, "unable to register device\n"); | 264 | dev_err(dev, "unable to register device\n"); |
265 | unregister_reboot_notifier(&timer->reboot_notifier); | 265 | ret = PTR_ERR(timer->rtc); |
266 | return PTR_ERR(timer->rtc); | 266 | goto err_notifier; |
267 | } | 267 | } |
268 | 268 | ||
269 | dev_info(dev, "registered, with irq %d\n", timer->irq); | 269 | dev_info(dev, "registered, with irq %d\n", timer->irq); |
270 | 270 | ||
271 | return 0; | ||
272 | |||
273 | err_notifier: | ||
274 | unregister_reboot_notifier(&timer->reboot_notifier); | ||
275 | |||
276 | err_clk: | ||
277 | if (timer->clk) | ||
278 | clk_disable_unprepare(timer->clk); | ||
279 | |||
271 | return ret; | 280 | return ret; |
272 | } | 281 | } |
273 | 282 | ||
diff --git a/drivers/rtc/rtc-cros-ec.c b/drivers/rtc/rtc-cros-ec.c new file mode 100644 index 000000000000..f0ea6899c731 --- /dev/null +++ b/drivers/rtc/rtc-cros-ec.c | |||
@@ -0,0 +1,413 @@ | |||
1 | /* | ||
2 | * RTC driver for Chrome OS Embedded Controller | ||
3 | * | ||
4 | * Copyright (c) 2017, Google, Inc | ||
5 | * | ||
6 | * Author: Stephen Barber <smbarber@chromium.org> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms and conditions of the GNU General Public License, | ||
10 | * version 2, as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/mfd/cros_ec.h> | ||
20 | #include <linux/mfd/cros_ec_commands.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/rtc.h> | ||
24 | #include <linux/slab.h> | ||
25 | |||
26 | #define DRV_NAME "cros-ec-rtc" | ||
27 | |||
28 | /** | ||
29 | * struct cros_ec_rtc - Driver data for EC RTC | ||
30 | * | ||
31 | * @cros_ec: Pointer to EC device | ||
32 | * @rtc: Pointer to RTC device | ||
33 | * @notifier: Notifier info for responding to EC events | ||
34 | * @saved_alarm: Alarm to restore when interrupts are reenabled | ||
35 | */ | ||
36 | struct cros_ec_rtc { | ||
37 | struct cros_ec_device *cros_ec; | ||
38 | struct rtc_device *rtc; | ||
39 | struct notifier_block notifier; | ||
40 | u32 saved_alarm; | ||
41 | }; | ||
42 | |||
43 | static int cros_ec_rtc_get(struct cros_ec_device *cros_ec, u32 command, | ||
44 | u32 *response) | ||
45 | { | ||
46 | int ret; | ||
47 | struct { | ||
48 | struct cros_ec_command msg; | ||
49 | struct ec_response_rtc data; | ||
50 | } __packed msg; | ||
51 | |||
52 | memset(&msg, 0, sizeof(msg)); | ||
53 | msg.msg.command = command; | ||
54 | msg.msg.insize = sizeof(msg.data); | ||
55 | |||
56 | ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); | ||
57 | if (ret < 0) { | ||
58 | dev_err(cros_ec->dev, | ||
59 | "error getting %s from EC: %d\n", | ||
60 | command == EC_CMD_RTC_GET_VALUE ? "time" : "alarm", | ||
61 | ret); | ||
62 | return ret; | ||
63 | } | ||
64 | |||
65 | *response = msg.data.time; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static int cros_ec_rtc_set(struct cros_ec_device *cros_ec, u32 command, | ||
71 | u32 param) | ||
72 | { | ||
73 | int ret = 0; | ||
74 | struct { | ||
75 | struct cros_ec_command msg; | ||
76 | struct ec_response_rtc data; | ||
77 | } __packed msg; | ||
78 | |||
79 | memset(&msg, 0, sizeof(msg)); | ||
80 | msg.msg.command = command; | ||
81 | msg.msg.outsize = sizeof(msg.data); | ||
82 | msg.data.time = param; | ||
83 | |||
84 | ret = cros_ec_cmd_xfer_status(cros_ec, &msg.msg); | ||
85 | if (ret < 0) { | ||
86 | dev_err(cros_ec->dev, "error setting %s on EC: %d\n", | ||
87 | command == EC_CMD_RTC_SET_VALUE ? "time" : "alarm", | ||
88 | ret); | ||
89 | return ret; | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | /* Read the current time from the EC. */ | ||
96 | static int cros_ec_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
97 | { | ||
98 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); | ||
99 | struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; | ||
100 | int ret; | ||
101 | u32 time; | ||
102 | |||
103 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, &time); | ||
104 | if (ret) { | ||
105 | dev_err(dev, "error getting time: %d\n", ret); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | rtc_time64_to_tm(time, tm); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /* Set the current EC time. */ | ||
115 | static int cros_ec_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
116 | { | ||
117 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); | ||
118 | struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; | ||
119 | int ret; | ||
120 | time64_t time; | ||
121 | |||
122 | time = rtc_tm_to_time64(tm); | ||
123 | if (time < 0 || time > U32_MAX) | ||
124 | return -EINVAL; | ||
125 | |||
126 | ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_VALUE, (u32)time); | ||
127 | if (ret < 0) { | ||
128 | dev_err(dev, "error setting time: %d\n", ret); | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* Read alarm time from RTC. */ | ||
136 | static int cros_ec_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
137 | { | ||
138 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); | ||
139 | struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; | ||
140 | int ret; | ||
141 | u32 current_time, alarm_offset; | ||
142 | |||
143 | /* | ||
144 | * The EC host command for getting the alarm is relative (i.e. 5 | ||
145 | * seconds from now) whereas rtc_wkalrm is absolute. Get the current | ||
146 | * RTC time first so we can calculate the relative time. | ||
147 | */ | ||
148 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); | ||
149 | if (ret < 0) { | ||
150 | dev_err(dev, "error getting time: %d\n", ret); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_ALARM, &alarm_offset); | ||
155 | if (ret < 0) { | ||
156 | dev_err(dev, "error getting alarm: %d\n", ret); | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | rtc_time64_to_tm(current_time + alarm_offset, &alrm->time); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | /* Set the EC's RTC alarm. */ | ||
166 | static int cros_ec_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
167 | { | ||
168 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); | ||
169 | struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; | ||
170 | int ret; | ||
171 | time64_t alarm_time; | ||
172 | u32 current_time, alarm_offset; | ||
173 | |||
174 | /* | ||
175 | * The EC host command for setting the alarm is relative | ||
176 | * (i.e. 5 seconds from now) whereas rtc_wkalrm is absolute. | ||
177 | * Get the current RTC time first so we can calculate the | ||
178 | * relative time. | ||
179 | */ | ||
180 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); | ||
181 | if (ret < 0) { | ||
182 | dev_err(dev, "error getting time: %d\n", ret); | ||
183 | return ret; | ||
184 | } | ||
185 | |||
186 | alarm_time = rtc_tm_to_time64(&alrm->time); | ||
187 | |||
188 | if (alarm_time < 0 || alarm_time > U32_MAX) | ||
189 | return -EINVAL; | ||
190 | |||
191 | if (!alrm->enabled) { | ||
192 | /* | ||
193 | * If the alarm is being disabled, send an alarm | ||
194 | * clear command. | ||
195 | */ | ||
196 | alarm_offset = EC_RTC_ALARM_CLEAR; | ||
197 | cros_ec_rtc->saved_alarm = (u32)alarm_time; | ||
198 | } else { | ||
199 | /* Don't set an alarm in the past. */ | ||
200 | if ((u32)alarm_time < current_time) | ||
201 | alarm_offset = EC_RTC_ALARM_CLEAR; | ||
202 | else | ||
203 | alarm_offset = (u32)alarm_time - current_time; | ||
204 | } | ||
205 | |||
206 | ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, alarm_offset); | ||
207 | if (ret < 0) { | ||
208 | dev_err(dev, "error setting alarm: %d\n", ret); | ||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static int cros_ec_rtc_alarm_irq_enable(struct device *dev, | ||
216 | unsigned int enabled) | ||
217 | { | ||
218 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(dev); | ||
219 | struct cros_ec_device *cros_ec = cros_ec_rtc->cros_ec; | ||
220 | int ret; | ||
221 | u32 current_time, alarm_offset, alarm_value; | ||
222 | |||
223 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_VALUE, ¤t_time); | ||
224 | if (ret < 0) { | ||
225 | dev_err(dev, "error getting time: %d\n", ret); | ||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | if (enabled) { | ||
230 | /* Restore saved alarm if it's still in the future. */ | ||
231 | if (cros_ec_rtc->saved_alarm < current_time) | ||
232 | alarm_offset = EC_RTC_ALARM_CLEAR; | ||
233 | else | ||
234 | alarm_offset = cros_ec_rtc->saved_alarm - current_time; | ||
235 | |||
236 | ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, | ||
237 | alarm_offset); | ||
238 | if (ret < 0) { | ||
239 | dev_err(dev, "error restoring alarm: %d\n", ret); | ||
240 | return ret; | ||
241 | } | ||
242 | } else { | ||
243 | /* Disable alarm, saving the old alarm value. */ | ||
244 | ret = cros_ec_rtc_get(cros_ec, EC_CMD_RTC_GET_ALARM, | ||
245 | &alarm_offset); | ||
246 | if (ret < 0) { | ||
247 | dev_err(dev, "error saving alarm: %d\n", ret); | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | alarm_value = current_time + alarm_offset; | ||
252 | |||
253 | /* | ||
254 | * If the current EC alarm is already past, we don't want | ||
255 | * to set an alarm when we go through the alarm irq enable | ||
256 | * path. | ||
257 | */ | ||
258 | if (alarm_value < current_time) | ||
259 | cros_ec_rtc->saved_alarm = EC_RTC_ALARM_CLEAR; | ||
260 | else | ||
261 | cros_ec_rtc->saved_alarm = alarm_value; | ||
262 | |||
263 | alarm_offset = EC_RTC_ALARM_CLEAR; | ||
264 | ret = cros_ec_rtc_set(cros_ec, EC_CMD_RTC_SET_ALARM, | ||
265 | alarm_offset); | ||
266 | if (ret < 0) { | ||
267 | dev_err(dev, "error disabling alarm: %d\n", ret); | ||
268 | return ret; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int cros_ec_rtc_event(struct notifier_block *nb, | ||
276 | unsigned long queued_during_suspend, | ||
277 | void *_notify) | ||
278 | { | ||
279 | struct cros_ec_rtc *cros_ec_rtc; | ||
280 | struct rtc_device *rtc; | ||
281 | struct cros_ec_device *cros_ec; | ||
282 | u32 host_event; | ||
283 | |||
284 | cros_ec_rtc = container_of(nb, struct cros_ec_rtc, notifier); | ||
285 | rtc = cros_ec_rtc->rtc; | ||
286 | cros_ec = cros_ec_rtc->cros_ec; | ||
287 | |||
288 | host_event = cros_ec_get_host_event(cros_ec); | ||
289 | if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC)) { | ||
290 | rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF); | ||
291 | return NOTIFY_OK; | ||
292 | } else { | ||
293 | return NOTIFY_DONE; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | static const struct rtc_class_ops cros_ec_rtc_ops = { | ||
298 | .read_time = cros_ec_rtc_read_time, | ||
299 | .set_time = cros_ec_rtc_set_time, | ||
300 | .read_alarm = cros_ec_rtc_read_alarm, | ||
301 | .set_alarm = cros_ec_rtc_set_alarm, | ||
302 | .alarm_irq_enable = cros_ec_rtc_alarm_irq_enable, | ||
303 | }; | ||
304 | |||
305 | #ifdef CONFIG_PM_SLEEP | ||
306 | static int cros_ec_rtc_suspend(struct device *dev) | ||
307 | { | ||
308 | struct platform_device *pdev = to_platform_device(dev); | ||
309 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(&pdev->dev); | ||
310 | |||
311 | if (device_may_wakeup(dev)) | ||
312 | enable_irq_wake(cros_ec_rtc->cros_ec->irq); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int cros_ec_rtc_resume(struct device *dev) | ||
318 | { | ||
319 | struct platform_device *pdev = to_platform_device(dev); | ||
320 | struct cros_ec_rtc *cros_ec_rtc = dev_get_drvdata(&pdev->dev); | ||
321 | |||
322 | if (device_may_wakeup(dev)) | ||
323 | disable_irq_wake(cros_ec_rtc->cros_ec->irq); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | #endif | ||
328 | |||
329 | static SIMPLE_DEV_PM_OPS(cros_ec_rtc_pm_ops, cros_ec_rtc_suspend, | ||
330 | cros_ec_rtc_resume); | ||
331 | |||
332 | static int cros_ec_rtc_probe(struct platform_device *pdev) | ||
333 | { | ||
334 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent); | ||
335 | struct cros_ec_device *cros_ec = ec_dev->ec_dev; | ||
336 | struct cros_ec_rtc *cros_ec_rtc; | ||
337 | struct rtc_time tm; | ||
338 | int ret; | ||
339 | |||
340 | cros_ec_rtc = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_rtc), | ||
341 | GFP_KERNEL); | ||
342 | if (!cros_ec_rtc) | ||
343 | return -ENOMEM; | ||
344 | |||
345 | platform_set_drvdata(pdev, cros_ec_rtc); | ||
346 | cros_ec_rtc->cros_ec = cros_ec; | ||
347 | |||
348 | /* Get initial time */ | ||
349 | ret = cros_ec_rtc_read_time(&pdev->dev, &tm); | ||
350 | if (ret) { | ||
351 | dev_err(&pdev->dev, "failed to read RTC time\n"); | ||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | ret = device_init_wakeup(&pdev->dev, 1); | ||
356 | if (ret) { | ||
357 | dev_err(&pdev->dev, "failed to initialize wakeup\n"); | ||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | cros_ec_rtc->rtc = devm_rtc_device_register(&pdev->dev, DRV_NAME, | ||
362 | &cros_ec_rtc_ops, | ||
363 | THIS_MODULE); | ||
364 | if (IS_ERR(cros_ec_rtc->rtc)) { | ||
365 | ret = PTR_ERR(cros_ec_rtc->rtc); | ||
366 | dev_err(&pdev->dev, "failed to register rtc device\n"); | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | /* Get RTC events from the EC. */ | ||
371 | cros_ec_rtc->notifier.notifier_call = cros_ec_rtc_event; | ||
372 | ret = blocking_notifier_chain_register(&cros_ec->event_notifier, | ||
373 | &cros_ec_rtc->notifier); | ||
374 | if (ret) { | ||
375 | dev_err(&pdev->dev, "failed to register notifier\n"); | ||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int cros_ec_rtc_remove(struct platform_device *pdev) | ||
383 | { | ||
384 | struct cros_ec_rtc *cros_ec_rtc = platform_get_drvdata(pdev); | ||
385 | struct device *dev = &pdev->dev; | ||
386 | int ret; | ||
387 | |||
388 | ret = blocking_notifier_chain_unregister( | ||
389 | &cros_ec_rtc->cros_ec->event_notifier, | ||
390 | &cros_ec_rtc->notifier); | ||
391 | if (ret) { | ||
392 | dev_err(dev, "failed to unregister notifier\n"); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | static struct platform_driver cros_ec_rtc_driver = { | ||
400 | .probe = cros_ec_rtc_probe, | ||
401 | .remove = cros_ec_rtc_remove, | ||
402 | .driver = { | ||
403 | .name = DRV_NAME, | ||
404 | .pm = &cros_ec_rtc_pm_ops, | ||
405 | }, | ||
406 | }; | ||
407 | |||
408 | module_platform_driver(cros_ec_rtc_driver); | ||
409 | |||
410 | MODULE_DESCRIPTION("RTC driver for Chrome OS ECs"); | ||
411 | MODULE_AUTHOR("Stephen Barber <smbarber@chromium.org>"); | ||
412 | MODULE_LICENSE("GPL"); | ||
413 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c new file mode 100644 index 000000000000..784221dfc9c7 --- /dev/null +++ b/drivers/rtc/rtc-mxc_v2.c | |||
@@ -0,0 +1,419 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Real Time Clock (RTC) Driver for i.MX53 | ||
4 | * Copyright (c) 2004-2011 Freescale Semiconductor, Inc. | ||
5 | * Copyright (c) 2017 Beckhoff Automation GmbH & Co. KG | ||
6 | */ | ||
7 | |||
8 | #include <linux/clk.h> | ||
9 | #include <linux/io.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/rtc.h> | ||
13 | |||
14 | #define SRTC_LPPDR_INIT 0x41736166 /* init for glitch detect */ | ||
15 | |||
16 | #define SRTC_LPCR_EN_LP BIT(3) /* lp enable */ | ||
17 | #define SRTC_LPCR_WAE BIT(4) /* lp wakeup alarm enable */ | ||
18 | #define SRTC_LPCR_ALP BIT(7) /* lp alarm flag */ | ||
19 | #define SRTC_LPCR_NSA BIT(11) /* lp non secure access */ | ||
20 | #define SRTC_LPCR_NVE BIT(14) /* lp non valid state exit bit */ | ||
21 | #define SRTC_LPCR_IE BIT(15) /* lp init state exit bit */ | ||
22 | |||
23 | #define SRTC_LPSR_ALP BIT(3) /* lp alarm flag */ | ||
24 | #define SRTC_LPSR_NVES BIT(14) /* lp non-valid state exit status */ | ||
25 | #define SRTC_LPSR_IES BIT(15) /* lp init state exit status */ | ||
26 | |||
27 | #define SRTC_LPSCMR 0x00 /* LP Secure Counter MSB Reg */ | ||
28 | #define SRTC_LPSCLR 0x04 /* LP Secure Counter LSB Reg */ | ||
29 | #define SRTC_LPSAR 0x08 /* LP Secure Alarm Reg */ | ||
30 | #define SRTC_LPCR 0x10 /* LP Control Reg */ | ||
31 | #define SRTC_LPSR 0x14 /* LP Status Reg */ | ||
32 | #define SRTC_LPPDR 0x18 /* LP Power Supply Glitch Detector Reg */ | ||
33 | |||
34 | /* max. number of retries to read registers, 120 was max during test */ | ||
35 | #define REG_READ_TIMEOUT 2000 | ||
36 | |||
37 | struct mxc_rtc_data { | ||
38 | struct rtc_device *rtc; | ||
39 | void __iomem *ioaddr; | ||
40 | struct clk *clk; | ||
41 | spinlock_t lock; /* protects register access */ | ||
42 | int irq; | ||
43 | }; | ||
44 | |||
45 | /* | ||
46 | * This function does write synchronization for writes to the lp srtc block. | ||
47 | * To take care of the asynchronous CKIL clock, all writes from the IP domain | ||
48 | * will be synchronized to the CKIL domain. | ||
49 | * The caller should hold the pdata->lock | ||
50 | */ | ||
51 | static void mxc_rtc_sync_lp_locked(struct device *dev, void __iomem *ioaddr) | ||
52 | { | ||
53 | unsigned int i; | ||
54 | |||
55 | /* Wait for 3 CKIL cycles */ | ||
56 | for (i = 0; i < 3; i++) { | ||
57 | const u32 count = readl(ioaddr + SRTC_LPSCLR); | ||
58 | unsigned int timeout = REG_READ_TIMEOUT; | ||
59 | |||
60 | while ((readl(ioaddr + SRTC_LPSCLR)) == count) { | ||
61 | if (!--timeout) { | ||
62 | dev_err_once(dev, "SRTC_LPSCLR stuck! Check your hw.\n"); | ||
63 | return; | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | /* This function is the RTC interrupt service routine. */ | ||
70 | static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) | ||
71 | { | ||
72 | struct device *dev = dev_id; | ||
73 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
74 | void __iomem *ioaddr = pdata->ioaddr; | ||
75 | unsigned long flags; | ||
76 | u32 lp_status; | ||
77 | u32 lp_cr; | ||
78 | |||
79 | spin_lock_irqsave(&pdata->lock, flags); | ||
80 | if (clk_enable(pdata->clk)) { | ||
81 | spin_unlock_irqrestore(&pdata->lock, flags); | ||
82 | return IRQ_NONE; | ||
83 | } | ||
84 | |||
85 | lp_status = readl(ioaddr + SRTC_LPSR); | ||
86 | lp_cr = readl(ioaddr + SRTC_LPCR); | ||
87 | |||
88 | /* update irq data & counter */ | ||
89 | if (lp_status & SRTC_LPSR_ALP) { | ||
90 | if (lp_cr & SRTC_LPCR_ALP) | ||
91 | rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF); | ||
92 | |||
93 | /* disable further lp alarm interrupts */ | ||
94 | lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); | ||
95 | } | ||
96 | |||
97 | /* Update interrupt enables */ | ||
98 | writel(lp_cr, ioaddr + SRTC_LPCR); | ||
99 | |||
100 | /* clear interrupt status */ | ||
101 | writel(lp_status, ioaddr + SRTC_LPSR); | ||
102 | |||
103 | mxc_rtc_sync_lp_locked(dev, ioaddr); | ||
104 | clk_disable(pdata->clk); | ||
105 | spin_unlock_irqrestore(&pdata->lock, flags); | ||
106 | return IRQ_HANDLED; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Enable clk and aquire spinlock | ||
111 | * @return 0 if successful; non-zero otherwise. | ||
112 | */ | ||
113 | static int mxc_rtc_lock(struct mxc_rtc_data *const pdata) | ||
114 | { | ||
115 | int ret; | ||
116 | |||
117 | spin_lock_irq(&pdata->lock); | ||
118 | ret = clk_enable(pdata->clk); | ||
119 | if (ret) { | ||
120 | spin_unlock_irq(&pdata->lock); | ||
121 | return ret; | ||
122 | } | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int mxc_rtc_unlock(struct mxc_rtc_data *const pdata) | ||
127 | { | ||
128 | clk_disable(pdata->clk); | ||
129 | spin_unlock_irq(&pdata->lock); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * This function reads the current RTC time into tm in Gregorian date. | ||
135 | * | ||
136 | * @param tm contains the RTC time value upon return | ||
137 | * | ||
138 | * @return 0 if successful; non-zero otherwise. | ||
139 | */ | ||
140 | static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
141 | { | ||
142 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
143 | const int clk_failed = clk_enable(pdata->clk); | ||
144 | |||
145 | if (!clk_failed) { | ||
146 | const time64_t now = readl(pdata->ioaddr + SRTC_LPSCMR); | ||
147 | |||
148 | rtc_time64_to_tm(now, tm); | ||
149 | clk_disable(pdata->clk); | ||
150 | return 0; | ||
151 | } | ||
152 | return clk_failed; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * This function sets the internal RTC time based on tm in Gregorian date. | ||
157 | * | ||
158 | * @param tm the time value to be set in the RTC | ||
159 | * | ||
160 | * @return 0 if successful; non-zero otherwise. | ||
161 | */ | ||
162 | static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
163 | { | ||
164 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
165 | time64_t time = rtc_tm_to_time64(tm); | ||
166 | int ret; | ||
167 | |||
168 | if (time > U32_MAX) { | ||
169 | dev_err(dev, "RTC exceeded by %llus\n", time - U32_MAX); | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | |||
173 | ret = mxc_rtc_lock(pdata); | ||
174 | if (ret) | ||
175 | return ret; | ||
176 | |||
177 | writel(time, pdata->ioaddr + SRTC_LPSCMR); | ||
178 | mxc_rtc_sync_lp_locked(dev, pdata->ioaddr); | ||
179 | return mxc_rtc_unlock(pdata); | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * This function reads the current alarm value into the passed in \b alrm | ||
184 | * argument. It updates the \b alrm's pending field value based on the whether | ||
185 | * an alarm interrupt occurs or not. | ||
186 | * | ||
187 | * @param alrm contains the RTC alarm value upon return | ||
188 | * | ||
189 | * @return 0 if successful; non-zero otherwise. | ||
190 | */ | ||
191 | static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
192 | { | ||
193 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
194 | void __iomem *ioaddr = pdata->ioaddr; | ||
195 | int ret; | ||
196 | |||
197 | ret = mxc_rtc_lock(pdata); | ||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | rtc_time_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time); | ||
202 | alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP); | ||
203 | return mxc_rtc_unlock(pdata); | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Enable/Disable alarm interrupt | ||
208 | * The caller should hold the pdata->lock | ||
209 | */ | ||
210 | static void mxc_rtc_alarm_irq_enable_locked(struct mxc_rtc_data *pdata, | ||
211 | unsigned int enable) | ||
212 | { | ||
213 | u32 lp_cr = readl(pdata->ioaddr + SRTC_LPCR); | ||
214 | |||
215 | if (enable) | ||
216 | lp_cr |= (SRTC_LPCR_ALP | SRTC_LPCR_WAE); | ||
217 | else | ||
218 | lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE); | ||
219 | |||
220 | writel(lp_cr, pdata->ioaddr + SRTC_LPCR); | ||
221 | } | ||
222 | |||
223 | static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) | ||
224 | { | ||
225 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
226 | int ret = mxc_rtc_lock(pdata); | ||
227 | |||
228 | if (ret) | ||
229 | return ret; | ||
230 | |||
231 | mxc_rtc_alarm_irq_enable_locked(pdata, enable); | ||
232 | return mxc_rtc_unlock(pdata); | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * This function sets the RTC alarm based on passed in alrm. | ||
237 | * | ||
238 | * @param alrm the alarm value to be set in the RTC | ||
239 | * | ||
240 | * @return 0 if successful; non-zero otherwise. | ||
241 | */ | ||
242 | static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
243 | { | ||
244 | const time64_t time = rtc_tm_to_time64(&alrm->time); | ||
245 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
246 | int ret = mxc_rtc_lock(pdata); | ||
247 | |||
248 | if (ret) | ||
249 | return ret; | ||
250 | |||
251 | if (time > U32_MAX) { | ||
252 | dev_err(dev, "Hopefully I am out of service by then :-(\n"); | ||
253 | return -EINVAL; | ||
254 | } | ||
255 | |||
256 | writel((u32)time, pdata->ioaddr + SRTC_LPSAR); | ||
257 | |||
258 | /* clear alarm interrupt status bit */ | ||
259 | writel(SRTC_LPSR_ALP, pdata->ioaddr + SRTC_LPSR); | ||
260 | mxc_rtc_sync_lp_locked(dev, pdata->ioaddr); | ||
261 | |||
262 | mxc_rtc_alarm_irq_enable_locked(pdata, alrm->enabled); | ||
263 | mxc_rtc_sync_lp_locked(dev, pdata->ioaddr); | ||
264 | mxc_rtc_unlock(pdata); | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static const struct rtc_class_ops mxc_rtc_ops = { | ||
269 | .read_time = mxc_rtc_read_time, | ||
270 | .set_time = mxc_rtc_set_time, | ||
271 | .read_alarm = mxc_rtc_read_alarm, | ||
272 | .set_alarm = mxc_rtc_set_alarm, | ||
273 | .alarm_irq_enable = mxc_rtc_alarm_irq_enable, | ||
274 | }; | ||
275 | |||
276 | static int mxc_rtc_wait_for_flag(void *__iomem ioaddr, int flag) | ||
277 | { | ||
278 | unsigned int timeout = REG_READ_TIMEOUT; | ||
279 | |||
280 | while (!(readl(ioaddr) & flag)) { | ||
281 | if (!--timeout) | ||
282 | return -EBUSY; | ||
283 | } | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int mxc_rtc_probe(struct platform_device *pdev) | ||
288 | { | ||
289 | struct mxc_rtc_data *pdata; | ||
290 | struct resource *res; | ||
291 | void __iomem *ioaddr; | ||
292 | int ret = 0; | ||
293 | |||
294 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
295 | if (!pdata) | ||
296 | return -ENOMEM; | ||
297 | |||
298 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
299 | pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res); | ||
300 | if (IS_ERR(pdata->ioaddr)) | ||
301 | return PTR_ERR(pdata->ioaddr); | ||
302 | |||
303 | ioaddr = pdata->ioaddr; | ||
304 | |||
305 | pdata->clk = devm_clk_get(&pdev->dev, NULL); | ||
306 | if (IS_ERR(pdata->clk)) { | ||
307 | dev_err(&pdev->dev, "unable to get rtc clock!\n"); | ||
308 | return PTR_ERR(pdata->clk); | ||
309 | } | ||
310 | |||
311 | spin_lock_init(&pdata->lock); | ||
312 | pdata->irq = platform_get_irq(pdev, 0); | ||
313 | if (pdata->irq < 0) | ||
314 | return pdata->irq; | ||
315 | |||
316 | device_init_wakeup(&pdev->dev, 1); | ||
317 | |||
318 | ret = clk_prepare_enable(pdata->clk); | ||
319 | if (ret) | ||
320 | return ret; | ||
321 | /* initialize glitch detect */ | ||
322 | writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR); | ||
323 | |||
324 | /* clear lp interrupt status */ | ||
325 | writel(0xFFFFFFFF, ioaddr + SRTC_LPSR); | ||
326 | |||
327 | /* move out of init state */ | ||
328 | writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), ioaddr + SRTC_LPCR); | ||
329 | ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_IES); | ||
330 | if (ret) { | ||
331 | dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_IES\n"); | ||
332 | clk_disable_unprepare(pdata->clk); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | /* move out of non-valid state */ | ||
337 | writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA | | ||
338 | SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR); | ||
339 | ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_NVES); | ||
340 | if (ret) { | ||
341 | dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_NVES\n"); | ||
342 | clk_disable_unprepare(pdata->clk); | ||
343 | return ret; | ||
344 | } | ||
345 | |||
346 | clk_disable(pdata->clk); | ||
347 | platform_set_drvdata(pdev, pdata); | ||
348 | ret = | ||
349 | devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, 0, | ||
350 | pdev->name, &pdev->dev); | ||
351 | if (ret < 0) { | ||
352 | dev_err(&pdev->dev, "interrupt not available.\n"); | ||
353 | clk_unprepare(pdata->clk); | ||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | pdata->rtc = | ||
358 | devm_rtc_device_register(&pdev->dev, pdev->name, &mxc_rtc_ops, | ||
359 | THIS_MODULE); | ||
360 | if (IS_ERR(pdata->rtc)) { | ||
361 | clk_unprepare(pdata->clk); | ||
362 | return PTR_ERR(pdata->rtc); | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int mxc_rtc_remove(struct platform_device *pdev) | ||
369 | { | ||
370 | struct mxc_rtc_data *pdata = platform_get_drvdata(pdev); | ||
371 | |||
372 | clk_disable_unprepare(pdata->clk); | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | #ifdef CONFIG_PM_SLEEP | ||
377 | static int mxc_rtc_suspend(struct device *dev) | ||
378 | { | ||
379 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
380 | |||
381 | if (device_may_wakeup(dev)) | ||
382 | enable_irq_wake(pdata->irq); | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | static int mxc_rtc_resume(struct device *dev) | ||
388 | { | ||
389 | struct mxc_rtc_data *pdata = dev_get_drvdata(dev); | ||
390 | |||
391 | if (device_may_wakeup(dev)) | ||
392 | disable_irq_wake(pdata->irq); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | #endif | ||
397 | |||
398 | static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume); | ||
399 | |||
400 | static const struct of_device_id mxc_ids[] = { | ||
401 | { .compatible = "fsl,imx53-rtc", }, | ||
402 | {} | ||
403 | }; | ||
404 | |||
405 | static struct platform_driver mxc_rtc_driver = { | ||
406 | .driver = { | ||
407 | .name = "mxc_rtc_v2", | ||
408 | .of_match_table = mxc_ids, | ||
409 | .pm = &mxc_rtc_pm_ops, | ||
410 | }, | ||
411 | .probe = mxc_rtc_probe, | ||
412 | .remove = mxc_rtc_remove, | ||
413 | }; | ||
414 | |||
415 | module_platform_driver(mxc_rtc_driver); | ||
416 | |||
417 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
418 | MODULE_DESCRIPTION("Real Time Clock (RTC) Driver for i.MX53"); | ||
419 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index 1d666ac9ef70..09ef802d6e54 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -753,8 +753,10 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
753 | 753 | ||
754 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 754 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
755 | rtc->base = devm_ioremap_resource(&pdev->dev, res); | 755 | rtc->base = devm_ioremap_resource(&pdev->dev, res); |
756 | if (IS_ERR(rtc->base)) | 756 | if (IS_ERR(rtc->base)) { |
757 | clk_disable_unprepare(rtc->clk); | ||
757 | return PTR_ERR(rtc->base); | 758 | return PTR_ERR(rtc->base); |
759 | } | ||
758 | 760 | ||
759 | platform_set_drvdata(pdev, rtc); | 761 | platform_set_drvdata(pdev, rtc); |
760 | 762 | ||
@@ -887,6 +889,7 @@ static int omap_rtc_probe(struct platform_device *pdev) | |||
887 | return 0; | 889 | return 0; |
888 | 890 | ||
889 | err: | 891 | err: |
892 | clk_disable_unprepare(rtc->clk); | ||
890 | device_init_wakeup(&pdev->dev, false); | 893 | device_init_wakeup(&pdev->dev, false); |
891 | rtc->type->lock(rtc); | 894 | rtc->type->lock(rtc); |
892 | pm_runtime_put_sync(&pdev->dev); | 895 | pm_runtime_put_sync(&pdev->dev); |
diff --git a/drivers/rtc/rtc-r7301.c b/drivers/rtc/rtc-r7301.c index 28d540885f3d..500e8c8a2605 100644 --- a/drivers/rtc/rtc-r7301.c +++ b/drivers/rtc/rtc-r7301.c | |||
@@ -95,7 +95,7 @@ static int rtc7301_wait_while_busy(struct rtc7301_priv *priv) | |||
95 | if (!(val & RTC7301_CONTROL_BUSY)) | 95 | if (!(val & RTC7301_CONTROL_BUSY)) |
96 | return 0; | 96 | return 0; |
97 | 97 | ||
98 | usleep_range(200, 300); | 98 | udelay(300); |
99 | } | 99 | } |
100 | 100 | ||
101 | return -ETIMEDOUT; | 101 | return -ETIMEDOUT; |
@@ -235,7 +235,7 @@ static int rtc7301_set_time(struct device *dev, struct rtc_time *tm) | |||
235 | spin_lock_irqsave(&priv->lock, flags); | 235 | spin_lock_irqsave(&priv->lock, flags); |
236 | 236 | ||
237 | rtc7301_stop(priv); | 237 | rtc7301_stop(priv); |
238 | usleep_range(200, 300); | 238 | udelay(300); |
239 | rtc7301_select_bank(priv, 0); | 239 | rtc7301_select_bank(priv, 0); |
240 | rtc7301_write_time(priv, tm, false); | 240 | rtc7301_write_time(priv, tm, false); |
241 | rtc7301_start(priv); | 241 | rtc7301_start(priv); |
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index 83d2bcca6a8f..b6c5eb97051c 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -164,17 +164,11 @@ static int r9701_probe(struct spi_device *spi) | |||
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int r9701_remove(struct spi_device *spi) | ||
168 | { | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static struct spi_driver r9701_driver = { | 167 | static struct spi_driver r9701_driver = { |
173 | .driver = { | 168 | .driver = { |
174 | .name = "rtc-r9701", | 169 | .name = "rtc-r9701", |
175 | }, | 170 | }, |
176 | .probe = r9701_probe, | 171 | .probe = r9701_probe, |
177 | .remove = r9701_remove, | ||
178 | }; | 172 | }; |
179 | 173 | ||
180 | module_spi_driver(r9701_driver); | 174 | module_spi_driver(r9701_driver); |
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index 3a5c3d7d0c77..f25dabe8fd02 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Amelie Delaunay 2016 | 2 | * Copyright (C) STMicroelectronics SA 2017 |
3 | * Author: Amelie Delaunay <amelie.delaunay@st.com> | 3 | * Author: Amelie Delaunay <amelie.delaunay@st.com> for STMicroelectronics. |
4 | * License terms: GNU General Public License (GPL), version 2 | 4 | * License terms: GNU General Public License (GPL), version 2 |
5 | */ | 5 | */ |
6 | 6 | ||
diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index 3d2216ccd860..5bc28eed1adf 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c | |||
@@ -201,8 +201,10 @@ static void __init sun6i_rtc_clk_init(struct device_node *node) | |||
201 | 201 | ||
202 | clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2), | 202 | clk_data = kzalloc(sizeof(*clk_data) + (sizeof(*clk_data->hws) * 2), |
203 | GFP_KERNEL); | 203 | GFP_KERNEL); |
204 | if (!clk_data) | 204 | if (!clk_data) { |
205 | kfree(rtc); | ||
205 | return; | 206 | return; |
207 | } | ||
206 | 208 | ||
207 | spin_lock_init(&rtc->lock); | 209 | spin_lock_init(&rtc->lock); |
208 | 210 | ||
diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h index a83f6498b95e..2b96e630e3b6 100644 --- a/include/linux/mfd/cros_ec_commands.h +++ b/include/linux/mfd/cros_ec_commands.h | |||
@@ -291,6 +291,9 @@ enum host_event_code { | |||
291 | /* EC desires to change state of host-controlled USB mux */ | 291 | /* EC desires to change state of host-controlled USB mux */ |
292 | EC_HOST_EVENT_USB_MUX = 28, | 292 | EC_HOST_EVENT_USB_MUX = 28, |
293 | 293 | ||
294 | /* EC RTC event occurred */ | ||
295 | EC_HOST_EVENT_RTC = 26, | ||
296 | |||
294 | /* | 297 | /* |
295 | * The high bit of the event mask is not used as a host event code. If | 298 | * The high bit of the event mask is not used as a host event code. If |
296 | * it reads back as set, then the entire event mask should be | 299 | * it reads back as set, then the entire event mask should be |
@@ -799,6 +802,8 @@ enum ec_feature_code { | |||
799 | EC_FEATURE_USB_MUX = 23, | 802 | EC_FEATURE_USB_MUX = 23, |
800 | /* Motion Sensor code has an internal software FIFO */ | 803 | /* Motion Sensor code has an internal software FIFO */ |
801 | EC_FEATURE_MOTION_SENSE_FIFO = 24, | 804 | EC_FEATURE_MOTION_SENSE_FIFO = 24, |
805 | /* EC has RTC feature that can be controlled by host commands */ | ||
806 | EC_FEATURE_RTC = 27, | ||
802 | }; | 807 | }; |
803 | 808 | ||
804 | #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) | 809 | #define EC_FEATURE_MASK_0(event_code) (1UL << (event_code % 32)) |
@@ -1709,6 +1714,9 @@ struct ec_response_rtc { | |||
1709 | #define EC_CMD_RTC_SET_VALUE 0x46 | 1714 | #define EC_CMD_RTC_SET_VALUE 0x46 |
1710 | #define EC_CMD_RTC_SET_ALARM 0x47 | 1715 | #define EC_CMD_RTC_SET_ALARM 0x47 |
1711 | 1716 | ||
1717 | /* Pass as param to SET_ALARM to clear the current alarm */ | ||
1718 | #define EC_RTC_ALARM_CLEAR 0 | ||
1719 | |||
1712 | /*****************************************************************************/ | 1720 | /*****************************************************************************/ |
1713 | /* Port80 log access */ | 1721 | /* Port80 log access */ |
1714 | 1722 | ||
diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 41319a2e409b..fc6c90b57be0 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h | |||
@@ -87,7 +87,6 @@ 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 | #define RTC_DEVICE_NAME_SIZE 20 | ||
91 | typedef struct rtc_task { | 90 | typedef struct rtc_task { |
92 | void (*func)(void *private_data); | 91 | void (*func)(void *private_data); |
93 | void *private_data; | 92 | void *private_data; |