Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rtc-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
"The bulk of the patches are about replacing the uie_unsupported struct
rtc_device member by a feature bit.

Subsystem:

- remove uie_unsupported, all users have been converted to clear
RTC_FEATURE_UPDATE_INTERRUPT and provide a reason

- RTCs with an alarm with a resolution of a minute are now letting
the core handle rounding down the alarm time

- fix use-after-free on device removal

New driver:

- OP-TEE RTC PTA

Drivers:

- sun6i: Add H616 support

- cmos: Fix the AltCentury for AMD platforms

- spear: set range"

* tag 'rtc-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (56 commits)
rtc: check if __rtc_read_time was successful
rtc: gamecube: Fix refcount leak in gamecube_rtc_read_offset_from_sram
rtc: mc146818-lib: Fix the AltCentury for AMD platforms
rtc: optee: add RTC driver for OP-TEE RTC PTA
rtc: pm8xxx: Return -ENODEV if set_time disallowed
rtc: pm8xxx: Attach wake irq to device
clk: sunxi-ng: sun6i-rtc: include clk/sunxi-ng.h
rtc: remove uie_unsupported
rtc: xgene: stop using uie_unsupported
rtc: hym8563: switch to RTC_FEATURE_UPDATE_INTERRUPT
rtc: hym8563: let the core handle the alarm resolution
rtc: hym8563: switch to devm_rtc_allocate_device
rtc: efi: switch to RTC_FEATURE_UPDATE_INTERRUPT
rtc: efi: switch to devm_rtc_allocate_device
rtc: add new RTC_FEATURE_ALARM_WAKEUP_ONLY feature
rtc: spear: fix spear_rtc_read_time
rtc: spear: drop uie_unsupported
rtc: spear: set range
rtc: spear: switch to devm_rtc_allocate_device
rtc: pcf8563: switch to RTC_FEATURE_UPDATE_INTERRUPT
...

+1204 -242
+72 -12
Documentation/devicetree/bindings/rtc/allwinner,sun6i-a31-rtc.yaml
··· 16 16 17 17 compatible: 18 18 oneOf: 19 - - const: allwinner,sun6i-a31-rtc 20 - - const: allwinner,sun8i-a23-rtc 21 - - const: allwinner,sun8i-h3-rtc 22 - - const: allwinner,sun8i-r40-rtc 23 - - const: allwinner,sun8i-v3-rtc 24 - - const: allwinner,sun50i-h5-rtc 19 + - enum: 20 + - allwinner,sun6i-a31-rtc 21 + - allwinner,sun8i-a23-rtc 22 + - allwinner,sun8i-h3-rtc 23 + - allwinner,sun8i-r40-rtc 24 + - allwinner,sun8i-v3-rtc 25 + - allwinner,sun50i-h5-rtc 26 + - allwinner,sun50i-h6-rtc 27 + - allwinner,sun50i-h616-rtc 28 + - allwinner,sun50i-r329-rtc 25 29 - items: 26 30 - const: allwinner,sun50i-a64-rtc 27 31 - const: allwinner,sun8i-h3-rtc 28 - - const: allwinner,sun50i-h6-rtc 32 + - items: 33 + - const: allwinner,sun20i-d1-rtc 34 + - const: allwinner,sun50i-r329-rtc 29 35 30 36 reg: 31 37 maxItems: 1 ··· 43 37 - description: RTC Alarm 1 44 38 45 39 clocks: 46 - maxItems: 1 40 + minItems: 1 41 + maxItems: 4 42 + 43 + clock-names: 44 + minItems: 1 45 + maxItems: 4 47 46 48 47 clock-output-names: 49 48 minItems: 1 ··· 96 85 enum: 97 86 - allwinner,sun8i-h3-rtc 98 87 - allwinner,sun50i-h5-rtc 88 + - allwinner,sun50i-h6-rtc 99 89 100 90 then: 101 91 properties: ··· 108 96 properties: 109 97 compatible: 110 98 contains: 111 - const: allwinner,sun50i-h6-rtc 99 + const: allwinner,sun50i-h616-rtc 112 100 113 101 then: 114 102 properties: 115 - clock-output-names: 103 + clocks: 116 104 minItems: 3 117 105 maxItems: 3 106 + items: 107 + - description: Bus clock for register access 108 + - description: 24 MHz oscillator 109 + - description: 32 kHz clock from the CCU 110 + 111 + clock-names: 112 + minItems: 3 113 + maxItems: 3 114 + items: 115 + - const: bus 116 + - const: hosc 117 + - const: pll-32k 118 + 119 + required: 120 + - clocks 121 + - clock-names 118 122 119 123 - if: 120 124 properties: 121 125 compatible: 122 126 contains: 123 - const: allwinner,sun8i-r40-rtc 127 + const: allwinner,sun50i-r329-rtc 128 + 129 + then: 130 + properties: 131 + clocks: 132 + minItems: 3 133 + maxItems: 4 134 + items: 135 + - description: Bus clock for register access 136 + - description: 24 MHz oscillator 137 + - description: AHB parent for internal SPI clock 138 + - description: External 32768 Hz oscillator 139 + 140 + clock-names: 141 + minItems: 3 142 + maxItems: 4 143 + items: 144 + - const: bus 145 + - const: hosc 146 + - const: ahb 147 + - const: ext-osc32k 148 + 149 + required: 150 + - clocks 151 + - clock-names 152 + 153 + - if: 154 + properties: 155 + compatible: 156 + contains: 157 + enum: 158 + - allwinner,sun8i-r40-rtc 159 + - allwinner,sun50i-h616-rtc 160 + - allwinner,sun50i-r329-rtc 124 161 125 162 then: 126 163 properties: ··· 188 127 - compatible 189 128 - reg 190 129 - interrupts 191 - - clock-output-names 192 130 193 131 additionalProperties: false 194 132
-25
Documentation/devicetree/bindings/rtc/atmel,at91sam9-rtc.txt
··· 1 - Atmel AT91SAM9260 Real Time Timer 2 - 3 - Required properties: 4 - - compatible: should be one of the following: 5 - - "atmel,at91sam9260-rtt" 6 - - "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt" 7 - - reg: should encode the memory region of the RTT controller 8 - - interrupts: rtt alarm/event interrupt 9 - - clocks: should contain the 32 KHz slow clk that will drive the RTT block. 10 - - atmel,rtt-rtc-time-reg: should encode the GPBR register used to store 11 - the time base when the RTT is used as an RTC. 12 - The first cell should point to the GPBR node and the second one 13 - encode the offset within the GPBR block (or in other words, the 14 - GPBR register used to store the time base). 15 - 16 - 17 - Example: 18 - 19 - rtt@fffffd20 { 20 - compatible = "atmel,at91sam9260-rtt"; 21 - reg = <0xfffffd20 0x10>; 22 - interrupts = <1 4 7>; 23 - clocks = <&clk32k>; 24 - atmel,rtt-rtc-time-reg = <&gpbr 0x0>; 25 - };
+69
Documentation/devicetree/bindings/rtc/atmel,at91sam9260-rtt.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2022 Microchip Technology, Inc. and its subsidiaries 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/rtc/atmel,at91sam9260-rtt.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Atmel AT91 RTT Device Tree Bindings 9 + 10 + allOf: 11 + - $ref: "rtc.yaml#" 12 + 13 + maintainers: 14 + - Alexandre Belloni <alexandre.belloni@bootlin.com> 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - items: 20 + - const: atmel,at91sam9260-rtt 21 + - items: 22 + - const: microchip,sam9x60-rtt 23 + - const: atmel,at91sam9260-rtt 24 + - items: 25 + - const: microchip,sama7g5-rtt 26 + - const: microchip,sam9x60-rtt 27 + - const: atmel,at91sam9260-rtt 28 + 29 + reg: 30 + maxItems: 1 31 + 32 + interrupts: 33 + maxItems: 1 34 + 35 + clocks: 36 + maxItems: 1 37 + 38 + atmel,rtt-rtc-time-reg: 39 + $ref: /schemas/types.yaml#/definitions/phandle-array 40 + items: 41 + - items: 42 + - description: Phandle to the GPBR node. 43 + - description: Offset within the GPBR block. 44 + description: 45 + Should encode the GPBR register used to store the time base when the 46 + RTT is used as an RTC. The first cell should point to the GPBR node 47 + and the second one encodes the offset within the GPBR block (or in 48 + other words, the GPBR register used to store the time base). 49 + 50 + required: 51 + - compatible 52 + - reg 53 + - interrupts 54 + - clocks 55 + - atmel,rtt-rtc-time-reg 56 + 57 + unevaluatedProperties: false 58 + 59 + examples: 60 + - | 61 + #include <dt-bindings/interrupt-controller/irq.h> 62 + 63 + rtc@fffffd20 { 64 + compatible = "atmel,at91sam9260-rtt"; 65 + reg = <0xfffffd20 0x10>; 66 + interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>; 67 + clocks = <&clk32k>; 68 + atmel,rtt-rtc-time-reg = <&gpbr 0x0>; 69 + };
+6
MAINTAINERS
··· 14622 14622 S: Maintained 14623 14623 F: drivers/char/hw_random/optee-rng.c 14624 14624 14625 + OP-TEE RTC DRIVER 14626 + M: Clément Léger <clement.leger@bootlin.com> 14627 + L: linux-rtc@vger.kernel.org 14628 + S: Maintained 14629 + F: drivers/rtc/rtc-optee.c 14630 + 14625 14631 OPA-VNIC DRIVER 14626 14632 M: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com> 14627 14633 M: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
+5
drivers/clk/sunxi-ng/Kconfig
··· 69 69 default MACH_SUN6I 70 70 depends on MACH_SUN6I || COMPILE_TEST 71 71 72 + config SUN6I_RTC_CCU 73 + tristate "Support for the Allwinner H616/R329 RTC CCU" 74 + default ARCH_SUNXI 75 + depends on ARCH_SUNXI || COMPILE_TEST 76 + 72 77 config SUN8I_A23_CCU 73 78 tristate "Support for the Allwinner A23 CCU" 74 79 default MACH_SUN8I
+2
drivers/clk/sunxi-ng/Makefile
··· 36 36 obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o 37 37 obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o 38 38 obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o 39 + obj-$(CONFIG_SUN6I_RTC_CCU) += sun6i-rtc-ccu.o 39 40 obj-$(CONFIG_SUN8I_A23_CCU) += sun8i-a23-ccu.o 40 41 obj-$(CONFIG_SUN8I_A33_CCU) += sun8i-a33-ccu.o 41 42 obj-$(CONFIG_SUN8I_A83T_CCU) += sun8i-a83t-ccu.o ··· 61 60 sun4i-a10-ccu-y += ccu-sun4i-a10.o 62 61 sun5i-ccu-y += ccu-sun5i.o 63 62 sun6i-a31-ccu-y += ccu-sun6i-a31.o 63 + sun6i-rtc-ccu-y += ccu-sun6i-rtc.o 64 64 sun8i-a23-ccu-y += ccu-sun8i-a23.o 65 65 sun8i-a33-ccu-y += ccu-sun8i-a33.o 66 66 sun8i-a83t-ccu-y += ccu-sun8i-a83t.o
+395
drivers/clk/sunxi-ng/ccu-sun6i-rtc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // Copyright (c) 2021 Samuel Holland <samuel@sholland.org> 4 + // 5 + 6 + #include <linux/clk.h> 7 + #include <linux/clk-provider.h> 8 + #include <linux/io.h> 9 + #include <linux/module.h> 10 + #include <linux/of_device.h> 11 + 12 + #include <linux/clk/sunxi-ng.h> 13 + 14 + #include "ccu_common.h" 15 + 16 + #include "ccu_div.h" 17 + #include "ccu_gate.h" 18 + #include "ccu_mux.h" 19 + 20 + #include "ccu-sun6i-rtc.h" 21 + 22 + #define IOSC_ACCURACY 300000000 /* 30% */ 23 + #define IOSC_RATE 16000000 24 + 25 + #define LOSC_RATE 32768 26 + #define LOSC_RATE_SHIFT 15 27 + 28 + #define LOSC_CTRL_REG 0x0 29 + #define LOSC_CTRL_KEY 0x16aa0000 30 + 31 + #define IOSC_32K_CLK_DIV_REG 0x8 32 + #define IOSC_32K_CLK_DIV GENMASK(4, 0) 33 + #define IOSC_32K_PRE_DIV 32 34 + 35 + #define IOSC_CLK_CALI_REG 0xc 36 + #define IOSC_CLK_CALI_DIV_ONES 22 37 + #define IOSC_CLK_CALI_EN BIT(1) 38 + #define IOSC_CLK_CALI_SRC_SEL BIT(0) 39 + 40 + #define LOSC_OUT_GATING_REG 0x60 41 + 42 + #define DCXO_CTRL_REG 0x160 43 + #define DCXO_CTRL_CLK16M_RC_EN BIT(0) 44 + 45 + struct sun6i_rtc_match_data { 46 + bool have_ext_osc32k : 1; 47 + bool have_iosc_calibration : 1; 48 + bool rtc_32k_single_parent : 1; 49 + const struct clk_parent_data *osc32k_fanout_parents; 50 + u8 osc32k_fanout_nparents; 51 + }; 52 + 53 + static bool have_iosc_calibration; 54 + 55 + static int ccu_iosc_enable(struct clk_hw *hw) 56 + { 57 + struct ccu_common *cm = hw_to_ccu_common(hw); 58 + 59 + return ccu_gate_helper_enable(cm, DCXO_CTRL_CLK16M_RC_EN); 60 + } 61 + 62 + static void ccu_iosc_disable(struct clk_hw *hw) 63 + { 64 + struct ccu_common *cm = hw_to_ccu_common(hw); 65 + 66 + return ccu_gate_helper_disable(cm, DCXO_CTRL_CLK16M_RC_EN); 67 + } 68 + 69 + static int ccu_iosc_is_enabled(struct clk_hw *hw) 70 + { 71 + struct ccu_common *cm = hw_to_ccu_common(hw); 72 + 73 + return ccu_gate_helper_is_enabled(cm, DCXO_CTRL_CLK16M_RC_EN); 74 + } 75 + 76 + static unsigned long ccu_iosc_recalc_rate(struct clk_hw *hw, 77 + unsigned long parent_rate) 78 + { 79 + struct ccu_common *cm = hw_to_ccu_common(hw); 80 + 81 + if (have_iosc_calibration) { 82 + u32 reg = readl(cm->base + IOSC_CLK_CALI_REG); 83 + 84 + /* 85 + * Recover the IOSC frequency by shifting the ones place of 86 + * (fixed-point divider * 32768) into bit zero. 87 + */ 88 + if (reg & IOSC_CLK_CALI_EN) 89 + return reg >> (IOSC_CLK_CALI_DIV_ONES - LOSC_RATE_SHIFT); 90 + } 91 + 92 + return IOSC_RATE; 93 + } 94 + 95 + static unsigned long ccu_iosc_recalc_accuracy(struct clk_hw *hw, 96 + unsigned long parent_accuracy) 97 + { 98 + return IOSC_ACCURACY; 99 + } 100 + 101 + static const struct clk_ops ccu_iosc_ops = { 102 + .enable = ccu_iosc_enable, 103 + .disable = ccu_iosc_disable, 104 + .is_enabled = ccu_iosc_is_enabled, 105 + .recalc_rate = ccu_iosc_recalc_rate, 106 + .recalc_accuracy = ccu_iosc_recalc_accuracy, 107 + }; 108 + 109 + static struct ccu_common iosc_clk = { 110 + .reg = DCXO_CTRL_REG, 111 + .hw.init = CLK_HW_INIT_NO_PARENT("iosc", &ccu_iosc_ops, 112 + CLK_GET_RATE_NOCACHE), 113 + }; 114 + 115 + static int ccu_iosc_32k_prepare(struct clk_hw *hw) 116 + { 117 + struct ccu_common *cm = hw_to_ccu_common(hw); 118 + u32 val; 119 + 120 + if (!have_iosc_calibration) 121 + return 0; 122 + 123 + val = readl(cm->base + IOSC_CLK_CALI_REG); 124 + writel(val | IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL, 125 + cm->base + IOSC_CLK_CALI_REG); 126 + 127 + return 0; 128 + } 129 + 130 + static void ccu_iosc_32k_unprepare(struct clk_hw *hw) 131 + { 132 + struct ccu_common *cm = hw_to_ccu_common(hw); 133 + u32 val; 134 + 135 + if (!have_iosc_calibration) 136 + return; 137 + 138 + val = readl(cm->base + IOSC_CLK_CALI_REG); 139 + writel(val & ~(IOSC_CLK_CALI_EN | IOSC_CLK_CALI_SRC_SEL), 140 + cm->base + IOSC_CLK_CALI_REG); 141 + } 142 + 143 + static unsigned long ccu_iosc_32k_recalc_rate(struct clk_hw *hw, 144 + unsigned long parent_rate) 145 + { 146 + struct ccu_common *cm = hw_to_ccu_common(hw); 147 + u32 val; 148 + 149 + if (have_iosc_calibration) { 150 + val = readl(cm->base + IOSC_CLK_CALI_REG); 151 + 152 + /* Assume the calibrated 32k clock is accurate. */ 153 + if (val & IOSC_CLK_CALI_SRC_SEL) 154 + return LOSC_RATE; 155 + } 156 + 157 + val = readl(cm->base + IOSC_32K_CLK_DIV_REG) & IOSC_32K_CLK_DIV; 158 + 159 + return parent_rate / IOSC_32K_PRE_DIV / (val + 1); 160 + } 161 + 162 + static unsigned long ccu_iosc_32k_recalc_accuracy(struct clk_hw *hw, 163 + unsigned long parent_accuracy) 164 + { 165 + struct ccu_common *cm = hw_to_ccu_common(hw); 166 + u32 val; 167 + 168 + if (have_iosc_calibration) { 169 + val = readl(cm->base + IOSC_CLK_CALI_REG); 170 + 171 + /* Assume the calibrated 32k clock is accurate. */ 172 + if (val & IOSC_CLK_CALI_SRC_SEL) 173 + return 0; 174 + } 175 + 176 + return parent_accuracy; 177 + } 178 + 179 + static const struct clk_ops ccu_iosc_32k_ops = { 180 + .prepare = ccu_iosc_32k_prepare, 181 + .unprepare = ccu_iosc_32k_unprepare, 182 + .recalc_rate = ccu_iosc_32k_recalc_rate, 183 + .recalc_accuracy = ccu_iosc_32k_recalc_accuracy, 184 + }; 185 + 186 + static struct ccu_common iosc_32k_clk = { 187 + .hw.init = CLK_HW_INIT_HW("iosc-32k", &iosc_clk.hw, 188 + &ccu_iosc_32k_ops, 189 + CLK_GET_RATE_NOCACHE), 190 + }; 191 + 192 + static const struct clk_hw *ext_osc32k[] = { NULL }; /* updated during probe */ 193 + 194 + static SUNXI_CCU_GATE_HWS(ext_osc32k_gate_clk, "ext-osc32k-gate", 195 + ext_osc32k, 0x0, BIT(4), 0); 196 + 197 + static const struct clk_hw *osc32k_parents[] = { 198 + &iosc_32k_clk.hw, 199 + &ext_osc32k_gate_clk.common.hw 200 + }; 201 + 202 + static struct clk_init_data osc32k_init_data = { 203 + .name = "osc32k", 204 + .ops = &ccu_mux_ops, 205 + .parent_hws = osc32k_parents, 206 + .num_parents = ARRAY_SIZE(osc32k_parents), /* updated during probe */ 207 + }; 208 + 209 + static struct ccu_mux osc32k_clk = { 210 + .mux = _SUNXI_CCU_MUX(0, 1), 211 + .common = { 212 + .reg = LOSC_CTRL_REG, 213 + .features = CCU_FEATURE_KEY_FIELD, 214 + .hw.init = &osc32k_init_data, 215 + }, 216 + }; 217 + 218 + /* This falls back to the global name for fwnodes without a named reference. */ 219 + static const struct clk_parent_data osc24M[] = { 220 + { .fw_name = "hosc", .name = "osc24M" } 221 + }; 222 + 223 + static struct ccu_gate osc24M_32k_clk = { 224 + .enable = BIT(16), 225 + .common = { 226 + .reg = LOSC_OUT_GATING_REG, 227 + .prediv = 750, 228 + .features = CCU_FEATURE_ALL_PREDIV, 229 + .hw.init = CLK_HW_INIT_PARENTS_DATA("osc24M-32k", osc24M, 230 + &ccu_gate_ops, 0), 231 + }, 232 + }; 233 + 234 + static const struct clk_hw *rtc_32k_parents[] = { 235 + &osc32k_clk.common.hw, 236 + &osc24M_32k_clk.common.hw 237 + }; 238 + 239 + static struct clk_init_data rtc_32k_init_data = { 240 + .name = "rtc-32k", 241 + .ops = &ccu_mux_ops, 242 + .parent_hws = rtc_32k_parents, 243 + .num_parents = ARRAY_SIZE(rtc_32k_parents), /* updated during probe */ 244 + }; 245 + 246 + static struct ccu_mux rtc_32k_clk = { 247 + .mux = _SUNXI_CCU_MUX(1, 1), 248 + .common = { 249 + .reg = LOSC_CTRL_REG, 250 + .features = CCU_FEATURE_KEY_FIELD, 251 + .hw.init = &rtc_32k_init_data, 252 + }, 253 + }; 254 + 255 + static struct clk_init_data osc32k_fanout_init_data = { 256 + .name = "osc32k-fanout", 257 + .ops = &ccu_mux_ops, 258 + /* parents are set during probe */ 259 + }; 260 + 261 + static struct ccu_mux osc32k_fanout_clk = { 262 + .enable = BIT(0), 263 + .mux = _SUNXI_CCU_MUX(1, 2), 264 + .common = { 265 + .reg = LOSC_OUT_GATING_REG, 266 + .hw.init = &osc32k_fanout_init_data, 267 + }, 268 + }; 269 + 270 + static struct ccu_common *sun6i_rtc_ccu_clks[] = { 271 + &iosc_clk, 272 + &iosc_32k_clk, 273 + &ext_osc32k_gate_clk.common, 274 + &osc32k_clk.common, 275 + &osc24M_32k_clk.common, 276 + &rtc_32k_clk.common, 277 + &osc32k_fanout_clk.common, 278 + }; 279 + 280 + static struct clk_hw_onecell_data sun6i_rtc_ccu_hw_clks = { 281 + .num = CLK_NUMBER, 282 + .hws = { 283 + [CLK_OSC32K] = &osc32k_clk.common.hw, 284 + [CLK_OSC32K_FANOUT] = &osc32k_fanout_clk.common.hw, 285 + [CLK_IOSC] = &iosc_clk.hw, 286 + [CLK_IOSC_32K] = &iosc_32k_clk.hw, 287 + [CLK_EXT_OSC32K_GATE] = &ext_osc32k_gate_clk.common.hw, 288 + [CLK_OSC24M_32K] = &osc24M_32k_clk.common.hw, 289 + [CLK_RTC_32K] = &rtc_32k_clk.common.hw, 290 + }, 291 + }; 292 + 293 + static const struct sunxi_ccu_desc sun6i_rtc_ccu_desc = { 294 + .ccu_clks = sun6i_rtc_ccu_clks, 295 + .num_ccu_clks = ARRAY_SIZE(sun6i_rtc_ccu_clks), 296 + 297 + .hw_clks = &sun6i_rtc_ccu_hw_clks, 298 + }; 299 + 300 + static const struct clk_parent_data sun50i_h6_osc32k_fanout_parents[] = { 301 + { .hw = &osc32k_clk.common.hw }, 302 + }; 303 + 304 + static const struct clk_parent_data sun50i_h616_osc32k_fanout_parents[] = { 305 + { .hw = &osc32k_clk.common.hw }, 306 + { .fw_name = "pll-32k" }, 307 + { .hw = &osc24M_32k_clk.common.hw } 308 + }; 309 + 310 + static const struct clk_parent_data sun50i_r329_osc32k_fanout_parents[] = { 311 + { .hw = &osc32k_clk.common.hw }, 312 + { .hw = &ext_osc32k_gate_clk.common.hw }, 313 + { .hw = &osc24M_32k_clk.common.hw } 314 + }; 315 + 316 + static const struct sun6i_rtc_match_data sun50i_h6_rtc_ccu_data = { 317 + .have_ext_osc32k = true, 318 + .have_iosc_calibration = true, 319 + .osc32k_fanout_parents = sun50i_h6_osc32k_fanout_parents, 320 + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_h6_osc32k_fanout_parents), 321 + }; 322 + 323 + static const struct sun6i_rtc_match_data sun50i_h616_rtc_ccu_data = { 324 + .have_iosc_calibration = true, 325 + .rtc_32k_single_parent = true, 326 + .osc32k_fanout_parents = sun50i_h616_osc32k_fanout_parents, 327 + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_h616_osc32k_fanout_parents), 328 + }; 329 + 330 + static const struct sun6i_rtc_match_data sun50i_r329_rtc_ccu_data = { 331 + .have_ext_osc32k = true, 332 + .osc32k_fanout_parents = sun50i_r329_osc32k_fanout_parents, 333 + .osc32k_fanout_nparents = ARRAY_SIZE(sun50i_r329_osc32k_fanout_parents), 334 + }; 335 + 336 + static const struct of_device_id sun6i_rtc_ccu_match[] = { 337 + { 338 + .compatible = "allwinner,sun50i-h6-rtc", 339 + .data = &sun50i_h6_rtc_ccu_data, 340 + }, 341 + { 342 + .compatible = "allwinner,sun50i-h616-rtc", 343 + .data = &sun50i_h616_rtc_ccu_data, 344 + }, 345 + { 346 + .compatible = "allwinner,sun50i-r329-rtc", 347 + .data = &sun50i_r329_rtc_ccu_data, 348 + }, 349 + }; 350 + 351 + int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) 352 + { 353 + const struct sun6i_rtc_match_data *data; 354 + struct clk *ext_osc32k_clk = NULL; 355 + const struct of_device_id *match; 356 + 357 + /* This driver is only used for newer variants of the hardware. */ 358 + match = of_match_device(sun6i_rtc_ccu_match, dev); 359 + if (!match) 360 + return 0; 361 + 362 + data = match->data; 363 + have_iosc_calibration = data->have_iosc_calibration; 364 + 365 + if (data->have_ext_osc32k) { 366 + const char *fw_name; 367 + 368 + /* ext-osc32k was the only input clock in the old binding. */ 369 + fw_name = of_property_read_bool(dev->of_node, "clock-names") 370 + ? "ext-osc32k" : NULL; 371 + ext_osc32k_clk = devm_clk_get_optional(dev, fw_name); 372 + if (IS_ERR(ext_osc32k_clk)) 373 + return PTR_ERR(ext_osc32k_clk); 374 + } 375 + 376 + if (ext_osc32k_clk) { 377 + /* Link ext-osc32k-gate to its parent. */ 378 + *ext_osc32k = __clk_get_hw(ext_osc32k_clk); 379 + } else { 380 + /* ext-osc32k-gate is an orphan, so do not register it. */ 381 + sun6i_rtc_ccu_hw_clks.hws[CLK_EXT_OSC32K_GATE] = NULL; 382 + osc32k_init_data.num_parents = 1; 383 + } 384 + 385 + if (data->rtc_32k_single_parent) 386 + rtc_32k_init_data.num_parents = 1; 387 + 388 + osc32k_fanout_init_data.parent_data = data->osc32k_fanout_parents; 389 + osc32k_fanout_init_data.num_parents = data->osc32k_fanout_nparents; 390 + 391 + return devm_sunxi_ccu_probe(dev, reg, &sun6i_rtc_ccu_desc); 392 + } 393 + 394 + MODULE_IMPORT_NS(SUNXI_CCU); 395 + MODULE_LICENSE("GPL");
+15
drivers/clk/sunxi-ng/ccu-sun6i-rtc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _CCU_SUN6I_RTC_H 4 + #define _CCU_SUN6I_RTC_H 5 + 6 + #include <dt-bindings/clock/sun6i-rtc.h> 7 + 8 + #define CLK_IOSC_32K 3 9 + #define CLK_EXT_OSC32K_GATE 4 10 + #define CLK_OSC24M_32K 5 11 + #define CLK_RTC_32K 6 12 + 13 + #define CLK_NUMBER (CLK_RTC_32K + 1) 14 + 15 + #endif /* _CCU_SUN6I_RTC_H */
+1
drivers/clk/sunxi-ng/ccu_common.h
··· 17 17 #define CCU_FEATURE_LOCK_REG BIT(5) 18 18 #define CCU_FEATURE_MMC_TIMING_SWITCH BIT(6) 19 19 #define CCU_FEATURE_SIGMA_DELTA_MOD BIT(7) 20 + #define CCU_FEATURE_KEY_FIELD BIT(8) 20 21 21 22 /* MMC timing mode switch bit */ 22 23 #define CCU_MMC_NEW_TIMING_MODE BIT(30)
+7
drivers/clk/sunxi-ng/ccu_mux.c
··· 12 12 #include "ccu_gate.h" 13 13 #include "ccu_mux.h" 14 14 15 + #define CCU_MUX_KEY_VALUE 0x16aa0000 16 + 15 17 static u16 ccu_mux_get_prediv(struct ccu_common *common, 16 18 struct ccu_mux_internal *cm, 17 19 int parent_index) ··· 193 191 spin_lock_irqsave(common->lock, flags); 194 192 195 193 reg = readl(common->base + common->reg); 194 + 195 + /* The key field always reads as zero. */ 196 + if (common->features & CCU_FEATURE_KEY_FIELD) 197 + reg |= CCU_MUX_KEY_VALUE; 198 + 196 199 reg &= ~GENMASK(cm->width + cm->shift - 1, cm->shift); 197 200 writel(reg | (index << cm->shift), common->base + common->reg); 198 201
+10
drivers/rtc/Kconfig
··· 1293 1293 This driver can also be built as a module. If so, the module 1294 1294 will be called rtc-opal. 1295 1295 1296 + config RTC_DRV_OPTEE 1297 + tristate "OP-TEE based RTC driver" 1298 + depends on OPTEE 1299 + help 1300 + Select this to get support for OP-TEE based RTC control on SoCs where 1301 + RTC are not accessible to the normal world (Linux). 1302 + 1303 + This driver can also be built as a module. If so, the module 1304 + will be called rtc-optee. 1305 + 1296 1306 config RTC_DRV_ZYNQMP 1297 1307 tristate "Xilinx Zynq Ultrascale+ MPSoC RTC" 1298 1308 depends on OF && HAS_IOMEM
+1
drivers/rtc/Makefile
··· 115 115 obj-$(CONFIG_RTC_DRV_NTXEC) += rtc-ntxec.o 116 116 obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o 117 117 obj-$(CONFIG_RTC_DRV_OPAL) += rtc-opal.o 118 + obj-$(CONFIG_RTC_DRV_OPTEE) += rtc-optee.o 118 119 obj-$(CONFIG_RTC_DRV_PALMAS) += rtc-palmas.o 119 120 obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o 120 121 obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
+9 -3
drivers/rtc/class.c
··· 26 26 static void rtc_device_release(struct device *dev) 27 27 { 28 28 struct rtc_device *rtc = to_rtc_device(dev); 29 + struct timerqueue_head *head = &rtc->timerqueue; 30 + struct timerqueue_node *node; 31 + 32 + mutex_lock(&rtc->ops_lock); 33 + while ((node = timerqueue_getnext(head))) 34 + timerqueue_del(head, node); 35 + mutex_unlock(&rtc->ops_lock); 36 + 37 + cancel_work_sync(&rtc->irqwork); 29 38 30 39 ida_simple_remove(&rtc_ida, rtc->id); 31 40 mutex_destroy(&rtc->ops_lock); ··· 398 389 399 390 if (!rtc->ops->set_alarm) 400 391 clear_bit(RTC_FEATURE_ALARM, rtc->features); 401 - 402 - if (rtc->uie_unsupported) 403 - clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 404 392 405 393 if (rtc->ops->set_offset) 406 394 set_bit(RTC_FEATURE_CORRECTION, rtc->features);
+5 -2
drivers/rtc/interface.c
··· 804 804 struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); 805 805 struct rtc_time tm; 806 806 ktime_t now; 807 + int err; 808 + 809 + err = __rtc_read_time(rtc, &tm); 810 + if (err) 811 + return err; 807 812 808 813 timer->enabled = 1; 809 - __rtc_read_time(rtc, &tm); 810 814 now = rtc_tm_to_ktime(tm); 811 815 812 816 /* Skip over expired timers */ ··· 824 820 trace_rtc_timer_enqueue(timer); 825 821 if (!next || ktime_before(timer->node.expires, next->expires)) { 826 822 struct rtc_wkalrm alarm; 827 - int err; 828 823 829 824 alarm.time = rtc_ktime_to_tm(timer->node.expires); 830 825 alarm.enabled = 1;
+1 -1
drivers/rtc/rtc-ds1307.c
··· 1955 1955 dev_info(ds1307->dev, 1956 1956 "'wakeup-source' is set, request for an IRQ is disabled!\n"); 1957 1957 /* We cannot support UIE mode if we do not have an IRQ line */ 1958 - ds1307->rtc->uie_unsupported = 1; 1958 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, ds1307->rtc->features); 1959 1959 } 1960 1960 1961 1961 if (want_irq) {
+6 -10
drivers/rtc/rtc-ds1685.c
··· 1273 1273 1274 1274 /* See if the platform doesn't support UIE. */ 1275 1275 if (pdata->uie_unsupported) 1276 - rtc_dev->uie_unsupported = 1; 1276 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc_dev->features); 1277 1277 1278 1278 rtc->dev = rtc_dev; 1279 1279 ··· 1285 1285 * there won't be an automatic way of notifying the kernel about it, 1286 1286 * unless ctrlc is explicitly polled. 1287 1287 */ 1288 - if (!pdata->no_irq) { 1289 - ret = platform_get_irq(pdev, 0); 1290 - if (ret <= 0) 1291 - return ret; 1292 - 1293 - rtc->irq_num = ret; 1294 - 1288 + rtc->irq_num = platform_get_irq(pdev, 0); 1289 + if (rtc->irq_num <= 0) { 1290 + clear_bit(RTC_FEATURE_ALARM, rtc_dev->features); 1291 + } else { 1295 1292 /* Request an IRQ. */ 1296 1293 ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_num, 1297 1294 NULL, ds1685_rtc_irq_handler, ··· 1302 1305 rtc->irq_num = 0; 1303 1306 } 1304 1307 } 1305 - rtc->no_irq = pdata->no_irq; 1306 1308 1307 1309 /* Setup complete. */ 1308 1310 ds1685_rtc_switch_to_bank0(rtc); ··· 1390 1394 * have been taken care of by the shutdown scripts and this 1391 1395 * is the final function call. 1392 1396 */ 1393 - if (!rtc->no_irq) 1397 + if (rtc->irq_num) 1394 1398 disable_irq_nosync(rtc->irq_num); 1395 1399 1396 1400 /* Oscillator must be on and the countdown chain enabled. */
+6 -4
drivers/rtc/rtc-efi.c
··· 261 261 if (efi.get_time(&eft, &cap) != EFI_SUCCESS) 262 262 return -ENODEV; 263 263 264 - rtc = devm_rtc_device_register(&dev->dev, "rtc-efi", &efi_rtc_ops, 265 - THIS_MODULE); 264 + rtc = devm_rtc_allocate_device(&dev->dev); 266 265 if (IS_ERR(rtc)) 267 266 return PTR_ERR(rtc); 268 267 269 - rtc->uie_unsupported = 1; 270 268 platform_set_drvdata(dev, rtc); 271 269 272 - return 0; 270 + rtc->ops = &efi_rtc_ops; 271 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 272 + set_bit(RTC_FEATURE_ALARM_WAKEUP_ONLY, rtc->features); 273 + 274 + return devm_rtc_register_device(rtc); 273 275 } 274 276 275 277 static struct platform_driver efi_rtc_driver = {
+1
drivers/rtc/rtc-gamecube.c
··· 235 235 } 236 236 237 237 ret = of_address_to_resource(np, 0, &res); 238 + of_node_put(np); 238 239 if (ret) { 239 240 pr_err("no io memory range found\n"); 240 241 return -1;
+8 -26
drivers/rtc/rtc-hym8563.c
··· 220 220 u8 buf[4]; 221 221 int ret; 222 222 223 - /* 224 - * The alarm has no seconds so deal with it 225 - */ 226 - if (alm_tm->tm_sec) { 227 - alm_tm->tm_sec = 0; 228 - alm_tm->tm_min++; 229 - if (alm_tm->tm_min >= 60) { 230 - alm_tm->tm_min = 0; 231 - alm_tm->tm_hour++; 232 - if (alm_tm->tm_hour >= 24) { 233 - alm_tm->tm_hour = 0; 234 - alm_tm->tm_mday++; 235 - if (alm_tm->tm_mday > 31) 236 - alm_tm->tm_mday = 0; 237 - } 238 - } 239 - } 240 - 241 223 ret = i2c_smbus_read_byte_data(client, HYM8563_CTL2); 242 224 if (ret < 0) 243 225 return ret; ··· 505 523 if (!hym8563) 506 524 return -ENOMEM; 507 525 526 + hym8563->rtc = devm_rtc_allocate_device(&client->dev); 527 + if (IS_ERR(hym8563->rtc)) 528 + return PTR_ERR(hym8563->rtc); 529 + 508 530 hym8563->client = client; 509 531 i2c_set_clientdata(client, hym8563); 510 532 ··· 543 557 dev_dbg(&client->dev, "rtc information is %s\n", 544 558 (ret & HYM8563_SEC_VL) ? "invalid" : "valid"); 545 559 546 - hym8563->rtc = devm_rtc_device_register(&client->dev, client->name, 547 - &hym8563_rtc_ops, THIS_MODULE); 548 - if (IS_ERR(hym8563->rtc)) 549 - return PTR_ERR(hym8563->rtc); 550 - 551 - /* the hym8563 alarm only supports a minute accuracy */ 552 - hym8563->rtc->uie_unsupported = 1; 560 + hym8563->rtc->ops = &hym8563_rtc_ops; 561 + set_bit(RTC_FEATURE_ALARM_RES_MINUTE, hym8563->rtc->features); 562 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, hym8563->rtc->features); 553 563 554 564 #ifdef CONFIG_COMMON_CLK 555 565 hym8563_clkout_register_clk(hym8563); 556 566 #endif 557 567 558 - return 0; 568 + return devm_rtc_register_device(hym8563->rtc); 559 569 } 560 570 561 571 static const struct i2c_device_id hym8563_id[] = {
+2 -4
drivers/rtc/rtc-m41t80.c
··· 932 932 m41t80_data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 933 933 m41t80_data->rtc->range_max = RTC_TIMESTAMP_END_2099; 934 934 935 - if (client->irq <= 0) { 936 - /* We cannot support UIE mode if we do not have an IRQ line */ 937 - m41t80_data->rtc->uie_unsupported = 1; 938 - } 935 + if (client->irq <= 0) 936 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, m41t80_data->rtc->features); 939 937 940 938 /* Make sure HT (Halt Update) bit is cleared */ 941 939 rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
+19 -3
drivers/rtc/rtc-mc146818-lib.c
··· 176 176 } 177 177 EXPORT_SYMBOL_GPL(mc146818_get_time); 178 178 179 + /* AMD systems don't allow access to AltCentury with DV1 */ 180 + static bool apply_amd_register_a_behavior(void) 181 + { 182 + #ifdef CONFIG_X86 183 + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD || 184 + boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) 185 + return true; 186 + #endif 187 + return false; 188 + } 189 + 179 190 /* Set the current date and time in the real time clock. */ 180 191 int mc146818_set_time(struct rtc_time *time) 181 192 { ··· 243 232 if (yrs >= 100) 244 233 yrs -= 100; 245 234 246 - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) 247 - || RTC_ALWAYS_BCD) { 235 + spin_lock_irqsave(&rtc_lock, flags); 236 + save_control = CMOS_READ(RTC_CONTROL); 237 + spin_unlock_irqrestore(&rtc_lock, flags); 238 + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 248 239 sec = bin2bcd(sec); 249 240 min = bin2bcd(min); 250 241 hrs = bin2bcd(hrs); ··· 260 247 save_control = CMOS_READ(RTC_CONTROL); 261 248 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 262 249 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 263 - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 250 + if (apply_amd_register_a_behavior()) 251 + CMOS_WRITE((save_freq_select & ~RTC_AMD_BANK_SELECT), RTC_FREQ_SELECT); 252 + else 253 + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 264 254 265 255 #ifdef CONFIG_MACH_DECSTATION 266 256 CMOS_WRITE(real_yrs, RTC_DEC_YEAR);
+2 -15
drivers/rtc/rtc-mpc5121.c
··· 210 210 struct mpc5121_rtc_data *rtc = dev_get_drvdata(dev); 211 211 struct mpc5121_rtc_regs __iomem *regs = rtc->regs; 212 212 213 - /* 214 - * the alarm has no seconds so deal with it 215 - */ 216 - if (alarm->time.tm_sec) { 217 - alarm->time.tm_sec = 0; 218 - alarm->time.tm_min++; 219 - if (alarm->time.tm_min >= 60) { 220 - alarm->time.tm_min = 0; 221 - alarm->time.tm_hour++; 222 - if (alarm->time.tm_hour >= 24) 223 - alarm->time.tm_hour = 0; 224 - } 225 - } 226 - 227 213 alarm->time.tm_mday = -1; 228 214 alarm->time.tm_mon = -1; 229 215 alarm->time.tm_year = -1; ··· 335 349 } 336 350 337 351 rtc->rtc->ops = &mpc5200_rtc_ops; 338 - rtc->rtc->uie_unsupported = 1; 352 + set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->rtc->features); 353 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->rtc->features); 339 354 rtc->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; 340 355 rtc->rtc->range_max = 65733206399ULL; /* 4052-12-31 23:59:59 */ 341 356
+1 -1
drivers/rtc/rtc-opal.c
··· 250 250 rtc->ops = &opal_rtc_ops; 251 251 rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; 252 252 rtc->range_max = RTC_TIMESTAMP_END_9999; 253 - rtc->uie_unsupported = 1; 253 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 254 254 255 255 return devm_rtc_register_device(rtc); 256 256 }
+362
drivers/rtc/rtc-optee.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2022 Microchip. 4 + */ 5 + 6 + #include <linux/device.h> 7 + #include <linux/kernel.h> 8 + #include <linux/module.h> 9 + #include <linux/rtc.h> 10 + #include <linux/tee_drv.h> 11 + 12 + #define RTC_INFO_VERSION 0x1 13 + 14 + #define TA_CMD_RTC_GET_INFO 0x0 15 + #define TA_CMD_RTC_GET_TIME 0x1 16 + #define TA_CMD_RTC_SET_TIME 0x2 17 + #define TA_CMD_RTC_GET_OFFSET 0x3 18 + #define TA_CMD_RTC_SET_OFFSET 0x4 19 + 20 + #define TA_RTC_FEATURE_CORRECTION BIT(0) 21 + 22 + struct optee_rtc_time { 23 + u32 tm_sec; 24 + u32 tm_min; 25 + u32 tm_hour; 26 + u32 tm_mday; 27 + u32 tm_mon; 28 + u32 tm_year; 29 + u32 tm_wday; 30 + }; 31 + 32 + struct optee_rtc_info { 33 + u64 version; 34 + u64 features; 35 + struct optee_rtc_time range_min; 36 + struct optee_rtc_time range_max; 37 + }; 38 + 39 + /** 40 + * struct optee_rtc - OP-TEE RTC private data 41 + * @dev: OP-TEE based RTC device. 42 + * @ctx: OP-TEE context handler. 43 + * @session_id: RTC TA session identifier. 44 + * @shm: Memory pool shared with RTC device. 45 + * @features: Bitfield of RTC features 46 + */ 47 + struct optee_rtc { 48 + struct device *dev; 49 + struct tee_context *ctx; 50 + u32 session_id; 51 + struct tee_shm *shm; 52 + u64 features; 53 + }; 54 + 55 + static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm) 56 + { 57 + struct optee_rtc *priv = dev_get_drvdata(dev); 58 + struct tee_ioctl_invoke_arg inv_arg = {0}; 59 + struct optee_rtc_time *optee_tm; 60 + struct tee_param param[4] = {0}; 61 + int ret; 62 + 63 + inv_arg.func = TA_CMD_RTC_GET_TIME; 64 + inv_arg.session = priv->session_id; 65 + inv_arg.num_params = 4; 66 + 67 + /* Fill invoke cmd params */ 68 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 69 + param[0].u.memref.shm = priv->shm; 70 + param[0].u.memref.size = sizeof(struct optee_rtc_time); 71 + 72 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 73 + if (ret < 0 || inv_arg.ret != 0) 74 + return ret ? ret : -EPROTO; 75 + 76 + optee_tm = tee_shm_get_va(priv->shm, 0); 77 + if (IS_ERR(optee_tm)) 78 + return PTR_ERR(optee_tm); 79 + 80 + if (param[0].u.memref.size != sizeof(*optee_tm)) 81 + return -EPROTO; 82 + 83 + tm->tm_sec = optee_tm->tm_sec; 84 + tm->tm_min = optee_tm->tm_min; 85 + tm->tm_hour = optee_tm->tm_hour; 86 + tm->tm_mday = optee_tm->tm_mday; 87 + tm->tm_mon = optee_tm->tm_mon; 88 + tm->tm_year = optee_tm->tm_year - 1900; 89 + tm->tm_wday = optee_tm->tm_wday; 90 + tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); 91 + 92 + return 0; 93 + } 94 + 95 + static int optee_rtc_settime(struct device *dev, struct rtc_time *tm) 96 + { 97 + struct optee_rtc *priv = dev_get_drvdata(dev); 98 + struct tee_ioctl_invoke_arg inv_arg = {0}; 99 + struct tee_param param[4] = {0}; 100 + struct optee_rtc_time optee_tm; 101 + void *rtc_data; 102 + int ret; 103 + 104 + optee_tm.tm_sec = tm->tm_sec; 105 + optee_tm.tm_min = tm->tm_min; 106 + optee_tm.tm_hour = tm->tm_hour; 107 + optee_tm.tm_mday = tm->tm_mday; 108 + optee_tm.tm_mon = tm->tm_mon; 109 + optee_tm.tm_year = tm->tm_year + 1900; 110 + optee_tm.tm_wday = tm->tm_wday; 111 + 112 + inv_arg.func = TA_CMD_RTC_SET_TIME; 113 + inv_arg.session = priv->session_id; 114 + inv_arg.num_params = 4; 115 + 116 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; 117 + param[0].u.memref.shm = priv->shm; 118 + param[0].u.memref.size = sizeof(struct optee_rtc_time); 119 + 120 + rtc_data = tee_shm_get_va(priv->shm, 0); 121 + if (IS_ERR(rtc_data)) 122 + return PTR_ERR(rtc_data); 123 + 124 + memcpy(rtc_data, &optee_tm, sizeof(struct optee_rtc_time)); 125 + 126 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 127 + if (ret < 0 || inv_arg.ret != 0) 128 + return ret ? ret : -EPROTO; 129 + 130 + return 0; 131 + } 132 + 133 + static int optee_rtc_readoffset(struct device *dev, long *offset) 134 + { 135 + struct optee_rtc *priv = dev_get_drvdata(dev); 136 + struct tee_ioctl_invoke_arg inv_arg = {0}; 137 + struct tee_param param[4] = {0}; 138 + int ret; 139 + 140 + if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 141 + return -EOPNOTSUPP; 142 + 143 + inv_arg.func = TA_CMD_RTC_GET_OFFSET; 144 + inv_arg.session = priv->session_id; 145 + inv_arg.num_params = 4; 146 + 147 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; 148 + 149 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 150 + if (ret < 0 || inv_arg.ret != 0) 151 + return ret ? ret : -EPROTO; 152 + 153 + *offset = param[0].u.value.a; 154 + 155 + return 0; 156 + } 157 + 158 + static int optee_rtc_setoffset(struct device *dev, long offset) 159 + { 160 + struct optee_rtc *priv = dev_get_drvdata(dev); 161 + struct tee_ioctl_invoke_arg inv_arg = {0}; 162 + struct tee_param param[4] = {0}; 163 + int ret; 164 + 165 + if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 166 + return -EOPNOTSUPP; 167 + 168 + inv_arg.func = TA_CMD_RTC_SET_OFFSET; 169 + inv_arg.session = priv->session_id; 170 + inv_arg.num_params = 4; 171 + 172 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 173 + param[0].u.value.a = offset; 174 + 175 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 176 + if (ret < 0 || inv_arg.ret != 0) 177 + return ret ? ret : -EPROTO; 178 + 179 + return 0; 180 + } 181 + 182 + static const struct rtc_class_ops optee_rtc_ops = { 183 + .read_time = optee_rtc_readtime, 184 + .set_time = optee_rtc_settime, 185 + .set_offset = optee_rtc_setoffset, 186 + .read_offset = optee_rtc_readoffset, 187 + }; 188 + 189 + static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, 190 + u64 *features) 191 + { 192 + struct optee_rtc *priv = dev_get_drvdata(dev); 193 + struct tee_ioctl_invoke_arg inv_arg = {0}; 194 + struct tee_param param[4] = {0}; 195 + struct optee_rtc_info *info; 196 + struct optee_rtc_time *tm; 197 + int ret; 198 + 199 + inv_arg.func = TA_CMD_RTC_GET_INFO; 200 + inv_arg.session = priv->session_id; 201 + inv_arg.num_params = 4; 202 + 203 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 204 + param[0].u.memref.shm = priv->shm; 205 + param[0].u.memref.size = sizeof(*info); 206 + 207 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 208 + if (ret < 0 || inv_arg.ret != 0) 209 + return ret ? ret : -EPROTO; 210 + 211 + info = tee_shm_get_va(priv->shm, 0); 212 + if (IS_ERR(info)) 213 + return PTR_ERR(info); 214 + 215 + if (param[0].u.memref.size != sizeof(*info)) 216 + return -EPROTO; 217 + 218 + if (info->version != RTC_INFO_VERSION) 219 + return -EPROTO; 220 + 221 + *features = info->features; 222 + 223 + tm = &info->range_min; 224 + rtc->range_min = mktime64(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, 225 + tm->tm_sec); 226 + tm = &info->range_max; 227 + rtc->range_max = mktime64(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, 228 + tm->tm_sec); 229 + 230 + return 0; 231 + } 232 + 233 + static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) 234 + { 235 + if (ver->impl_id == TEE_IMPL_ID_OPTEE) 236 + return 1; 237 + else 238 + return 0; 239 + } 240 + 241 + static int optee_rtc_probe(struct device *dev) 242 + { 243 + struct tee_client_device *rtc_device = to_tee_client_device(dev); 244 + struct tee_ioctl_open_session_arg sess_arg; 245 + struct optee_rtc *priv; 246 + struct rtc_device *rtc; 247 + struct tee_shm *shm; 248 + int ret, err; 249 + 250 + memset(&sess_arg, 0, sizeof(sess_arg)); 251 + 252 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 253 + if (!priv) 254 + return -ENOMEM; 255 + 256 + rtc = devm_rtc_allocate_device(dev); 257 + if (IS_ERR(rtc)) 258 + return PTR_ERR(rtc); 259 + 260 + /* Open context with TEE driver */ 261 + priv->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); 262 + if (IS_ERR(priv->ctx)) 263 + return -ENODEV; 264 + 265 + /* Open session with rtc Trusted App */ 266 + export_uuid(sess_arg.uuid, &rtc_device->id.uuid); 267 + sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; 268 + 269 + ret = tee_client_open_session(priv->ctx, &sess_arg, NULL); 270 + if (ret < 0 || sess_arg.ret != 0) { 271 + dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret); 272 + err = -EINVAL; 273 + goto out_ctx; 274 + } 275 + priv->session_id = sess_arg.session; 276 + 277 + shm = tee_shm_alloc_kernel_buf(priv->ctx, sizeof(struct optee_rtc_info)); 278 + if (IS_ERR(shm)) { 279 + dev_err(priv->dev, "tee_shm_alloc_kernel_buf failed\n"); 280 + err = PTR_ERR(shm); 281 + goto out_sess; 282 + } 283 + 284 + priv->shm = shm; 285 + priv->dev = dev; 286 + dev_set_drvdata(dev, priv); 287 + 288 + rtc->ops = &optee_rtc_ops; 289 + 290 + err = optee_rtc_read_info(dev, rtc, &priv->features); 291 + if (err) { 292 + dev_err(dev, "Failed to get RTC features from OP-TEE\n"); 293 + goto out_shm; 294 + } 295 + 296 + err = devm_rtc_register_device(rtc); 297 + if (err) 298 + goto out_shm; 299 + 300 + /* 301 + * We must clear this bit after registering because rtc_register_device 302 + * will set it if it sees that .set_offset is provided. 303 + */ 304 + if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 305 + clear_bit(RTC_FEATURE_CORRECTION, rtc->features); 306 + 307 + return 0; 308 + 309 + out_shm: 310 + tee_shm_free(priv->shm); 311 + out_sess: 312 + tee_client_close_session(priv->ctx, priv->session_id); 313 + out_ctx: 314 + tee_client_close_context(priv->ctx); 315 + 316 + return err; 317 + } 318 + 319 + static int optee_rtc_remove(struct device *dev) 320 + { 321 + struct optee_rtc *priv = dev_get_drvdata(dev); 322 + 323 + tee_client_close_session(priv->ctx, priv->session_id); 324 + tee_client_close_context(priv->ctx); 325 + 326 + return 0; 327 + } 328 + 329 + static const struct tee_client_device_id optee_rtc_id_table[] = { 330 + {UUID_INIT(0xf389f8c8, 0x845f, 0x496c, 331 + 0x8b, 0xbe, 0xd6, 0x4b, 0xd2, 0x4c, 0x92, 0xfd)}, 332 + {} 333 + }; 334 + 335 + MODULE_DEVICE_TABLE(tee, optee_rtc_id_table); 336 + 337 + static struct tee_client_driver optee_rtc_driver = { 338 + .id_table = optee_rtc_id_table, 339 + .driver = { 340 + .name = "optee_rtc", 341 + .bus = &tee_bus_type, 342 + .probe = optee_rtc_probe, 343 + .remove = optee_rtc_remove, 344 + }, 345 + }; 346 + 347 + static int __init optee_rtc_mod_init(void) 348 + { 349 + return driver_register(&optee_rtc_driver.driver); 350 + } 351 + 352 + static void __exit optee_rtc_mod_exit(void) 353 + { 354 + driver_unregister(&optee_rtc_driver.driver); 355 + } 356 + 357 + module_init(optee_rtc_mod_init); 358 + module_exit(optee_rtc_mod_exit); 359 + 360 + MODULE_LICENSE("GPL v2"); 361 + MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>"); 362 + MODULE_DESCRIPTION("OP-TEE based RTC driver");
+2 -1
drivers/rtc/rtc-pcf2123.c
··· 427 427 * support to this driver to generate interrupts more than once 428 428 * per minute. 429 429 */ 430 - rtc->uie_unsupported = 1; 430 + set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features); 431 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 431 432 rtc->ops = &pcf2123_rtc_ops; 432 433 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 433 434 rtc->range_max = RTC_TIMESTAMP_END_2099;
+16 -3
drivers/rtc/rtc-pcf2127.c
··· 374 374 static int pcf2127_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 375 375 { 376 376 struct pcf2127 *pcf2127 = dev_get_drvdata(dev); 377 - unsigned int buf[5], ctrl2; 377 + u8 buf[5]; 378 + unsigned int ctrl2; 378 379 int ret; 379 380 380 381 ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL2, &ctrl2); ··· 656 655 pcf2127->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 657 656 pcf2127->rtc->range_max = RTC_TIMESTAMP_END_2099; 658 657 pcf2127->rtc->set_start_time = true; /* Sets actual start to 1970 */ 659 - pcf2127->rtc->uie_unsupported = 1; 658 + set_bit(RTC_FEATURE_ALARM_RES_2S, pcf2127->rtc->features); 659 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, pcf2127->rtc->features); 660 660 clear_bit(RTC_FEATURE_ALARM, pcf2127->rtc->features); 661 661 662 662 if (alarm_irq > 0) { 663 + unsigned long flags; 664 + 665 + /* 666 + * If flags = 0, devm_request_threaded_irq() will use IRQ flags 667 + * obtained from device tree. 668 + */ 669 + if (dev_fwnode(dev)) 670 + flags = 0; 671 + else 672 + flags = IRQF_TRIGGER_LOW; 673 + 663 674 ret = devm_request_threaded_irq(dev, alarm_irq, NULL, 664 675 pcf2127_rtc_irq, 665 - IRQF_TRIGGER_LOW | IRQF_ONESHOT, 676 + flags | IRQF_ONESHOT, 666 677 dev_name(dev), dev); 667 678 if (ret) { 668 679 dev_err(dev, "failed to request alarm irq\n");
+2 -1
drivers/rtc/rtc-pcf85063.c
··· 616 616 pcf85063->rtc->ops = &pcf85063_rtc_ops; 617 617 pcf85063->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 618 618 pcf85063->rtc->range_max = RTC_TIMESTAMP_END_2099; 619 - pcf85063->rtc->uie_unsupported = 1; 619 + set_bit(RTC_FEATURE_ALARM_RES_2S, pcf85063->rtc->features); 620 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, pcf85063->rtc->features); 620 621 clear_bit(RTC_FEATURE_ALARM, pcf85063->rtc->features); 621 622 622 623 if (config->has_alarms && client->irq > 0) {
+4 -11
drivers/rtc/rtc-pcf8523.c
··· 212 212 if (err < 0) 213 213 return err; 214 214 215 - /* The alarm has no seconds, round up to nearest minute */ 216 - if (tm->time.tm_sec) { 217 - time64_t alarm_time = rtc_tm_to_time64(&tm->time); 218 - 219 - alarm_time += 60 - tm->time.tm_sec; 220 - rtc_time64_to_tm(alarm_time, &tm->time); 221 - } 222 - 223 215 regs[0] = bin2bcd(tm->time.tm_min); 224 216 regs[1] = bin2bcd(tm->time.tm_hour); 225 217 regs[2] = bin2bcd(tm->time.tm_mday); ··· 232 240 { 233 241 struct pcf8523 *pcf8523 = dev_get_drvdata(dev); 234 242 int ret; 243 + u32 value; 235 244 236 245 switch(param->param) { 237 - u32 value; 238 246 239 247 case RTC_PARAM_BACKUP_SWITCH_MODE: 240 248 ret = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL3, &value); ··· 271 279 static int pcf8523_param_set(struct device *dev, struct rtc_param *param) 272 280 { 273 281 struct pcf8523 *pcf8523 = dev_get_drvdata(dev); 282 + u8 mode; 274 283 275 284 switch(param->param) { 276 - u8 mode; 277 285 case RTC_PARAM_BACKUP_SWITCH_MODE: 278 286 switch (param->uvalue) { 279 287 case RTC_BSM_DISABLED: ··· 442 450 rtc->ops = &pcf8523_rtc_ops; 443 451 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 444 452 rtc->range_max = RTC_TIMESTAMP_END_2099; 445 - rtc->uie_unsupported = 1; 453 + set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features); 454 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features); 446 455 447 456 if (client->irq > 0) { 448 457 err = regmap_write(pcf8523->regmap, PCF8523_TMR_CLKOUT_CTRL, 0x38);
+2 -14
drivers/rtc/rtc-pcf8563.c
··· 330 330 unsigned char buf[4]; 331 331 int err; 332 332 333 - /* The alarm has no seconds, round up to nearest minute */ 334 - if (tm->time.tm_sec) { 335 - time64_t alarm_time = rtc_tm_to_time64(&tm->time); 336 - 337 - alarm_time += 60 - tm->time.tm_sec; 338 - rtc_time64_to_tm(alarm_time, &tm->time); 339 - } 340 - 341 - dev_dbg(dev, "%s, min=%d hour=%d wday=%d mday=%d " 342 - "enabled=%d pending=%d\n", __func__, 343 - tm->time.tm_min, tm->time.tm_hour, tm->time.tm_wday, 344 - tm->time.tm_mday, tm->enabled, tm->pending); 345 - 346 333 buf[0] = bin2bcd(tm->time.tm_min); 347 334 buf[1] = bin2bcd(tm->time.tm_hour); 348 335 buf[2] = bin2bcd(tm->time.tm_mday); ··· 552 565 553 566 pcf8563->rtc->ops = &pcf8563_rtc_ops; 554 567 /* the pcf8563 alarm only supports a minute accuracy */ 555 - pcf8563->rtc->uie_unsupported = 1; 568 + set_bit(RTC_FEATURE_ALARM_RES_MINUTE, pcf8563->rtc->features); 569 + clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, pcf8563->rtc->features); 556 570 pcf8563->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 557 571 pcf8563->rtc->range_max = RTC_TIMESTAMP_END_2099; 558 572 pcf8563->rtc->set_start_time = true;
+3 -3
drivers/rtc/rtc-pl031.c
··· 350 350 } 351 351 } 352 352 353 - if (!adev->irq[0]) 354 - clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features); 355 - 356 353 device_init_wakeup(&adev->dev, true); 357 354 ldata->rtc = devm_rtc_allocate_device(&adev->dev); 358 355 if (IS_ERR(ldata->rtc)) { 359 356 ret = PTR_ERR(ldata->rtc); 360 357 goto out; 361 358 } 359 + 360 + if (!adev->irq[0]) 361 + clear_bit(RTC_FEATURE_ALARM, ldata->rtc->features); 362 362 363 363 ldata->rtc->ops = ops; 364 364 ldata->rtc->range_min = vendor->range_min;
+11 -22
drivers/rtc/rtc-pm8xxx.c
··· 7 7 #include <linux/rtc.h> 8 8 #include <linux/platform_device.h> 9 9 #include <linux/pm.h> 10 + #include <linux/pm_wakeirq.h> 10 11 #include <linux/regmap.h> 11 12 #include <linux/slab.h> 12 13 #include <linux/spinlock.h> ··· 84 83 const struct pm8xxx_rtc_regs *regs = rtc_dd->regs; 85 84 86 85 if (!rtc_dd->allow_set_time) 87 - return -EACCES; 86 + return -ENODEV; 88 87 89 88 secs = rtc_tm_to_time64(tm); 90 89 ··· 528 527 return rc; 529 528 } 530 529 531 - return devm_rtc_register_device(rtc_dd->rtc); 532 - } 530 + rc = devm_rtc_register_device(rtc_dd->rtc); 531 + if (rc) 532 + return rc; 533 533 534 - #ifdef CONFIG_PM_SLEEP 535 - static int pm8xxx_rtc_resume(struct device *dev) 536 - { 537 - struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); 538 - 539 - if (device_may_wakeup(dev)) 540 - disable_irq_wake(rtc_dd->rtc_alarm_irq); 534 + rc = dev_pm_set_wake_irq(&pdev->dev, rtc_dd->rtc_alarm_irq); 535 + if (rc) 536 + return rc; 541 537 542 538 return 0; 543 539 } 544 540 545 - static int pm8xxx_rtc_suspend(struct device *dev) 541 + static int pm8xxx_remove(struct platform_device *pdev) 546 542 { 547 - struct pm8xxx_rtc *rtc_dd = dev_get_drvdata(dev); 548 - 549 - if (device_may_wakeup(dev)) 550 - enable_irq_wake(rtc_dd->rtc_alarm_irq); 551 - 543 + dev_pm_clear_wake_irq(&pdev->dev); 552 544 return 0; 553 545 } 554 - #endif 555 - 556 - static SIMPLE_DEV_PM_OPS(pm8xxx_rtc_pm_ops, 557 - pm8xxx_rtc_suspend, 558 - pm8xxx_rtc_resume); 559 546 560 547 static struct platform_driver pm8xxx_rtc_driver = { 561 548 .probe = pm8xxx_rtc_probe, 549 + .remove = pm8xxx_remove, 562 550 .driver = { 563 551 .name = "rtc-pm8xxx", 564 - .pm = &pm8xxx_rtc_pm_ops, 565 552 .of_match_table = pm8xxx_id_table, 566 553 }, 567 554 };
+14 -11
drivers/rtc/rtc-spear.c
··· 204 204 /* we don't report wday/yday/isdst ... */ 205 205 rtc_wait_not_busy(config); 206 206 207 - time = readl(config->ioaddr + TIME_REG); 208 - date = readl(config->ioaddr + DATE_REG); 207 + do { 208 + time = readl(config->ioaddr + TIME_REG); 209 + date = readl(config->ioaddr + DATE_REG); 210 + } while (time == readl(config->ioaddr + TIME_REG)); 209 211 tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK; 210 212 tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK; 211 213 tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK; ··· 354 352 if (!config) 355 353 return -ENOMEM; 356 354 355 + config->rtc = devm_rtc_allocate_device(&pdev->dev); 356 + if (IS_ERR(config->rtc)) 357 + return PTR_ERR(config->rtc); 358 + 357 359 /* alarm irqs */ 358 360 irq = platform_get_irq(pdev, 0); 359 361 if (irq < 0) ··· 386 380 spin_lock_init(&config->lock); 387 381 platform_set_drvdata(pdev, config); 388 382 389 - config->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 390 - &spear_rtc_ops, THIS_MODULE); 391 - if (IS_ERR(config->rtc)) { 392 - dev_err(&pdev->dev, "can't register RTC device, err %ld\n", 393 - PTR_ERR(config->rtc)); 394 - status = PTR_ERR(config->rtc); 395 - goto err_disable_clock; 396 - } 383 + config->rtc->ops = &spear_rtc_ops; 384 + config->rtc->range_min = RTC_TIMESTAMP_BEGIN_0000; 385 + config->rtc->range_min = RTC_TIMESTAMP_END_9999; 397 386 398 - config->rtc->uie_unsupported = 1; 387 + status = devm_rtc_register_device(config->rtc); 388 + if (status) 389 + goto err_disable_clock; 399 390 400 391 if (!device_can_wakeup(&pdev->dev)) 401 392 device_init_wakeup(&pdev->dev, 1);
+120 -62
drivers/rtc/rtc-sun6i.c
··· 13 13 14 14 #include <linux/clk.h> 15 15 #include <linux/clk-provider.h> 16 + #include <linux/clk/sunxi-ng.h> 16 17 #include <linux/delay.h> 17 18 #include <linux/err.h> 18 19 #include <linux/fs.h> ··· 49 48 50 49 /* Alarm 0 (counter) */ 51 50 #define SUN6I_ALRM_COUNTER 0x0020 52 - #define SUN6I_ALRM_CUR_VAL 0x0024 51 + /* This holds the remaining alarm seconds on older SoCs (current value) */ 52 + #define SUN6I_ALRM_COUNTER_HMS 0x0024 53 53 #define SUN6I_ALRM_EN 0x0028 54 54 #define SUN6I_ALRM_EN_CNT_EN BIT(0) 55 55 #define SUN6I_ALRM_IRQ_EN 0x002c ··· 112 110 #define SUN6I_YEAR_MIN 1970 113 111 #define SUN6I_YEAR_OFF (SUN6I_YEAR_MIN - 1900) 114 112 113 + #define SECS_PER_DAY (24 * 3600ULL) 114 + 115 115 /* 116 116 * There are other differences between models, including: 117 117 * ··· 137 133 unsigned int has_auto_swt : 1; 138 134 }; 139 135 136 + #define RTC_LINEAR_DAY BIT(0) 137 + 140 138 struct sun6i_rtc_dev { 141 139 struct rtc_device *rtc; 142 140 const struct sun6i_rtc_clk_data *data; 143 141 void __iomem *base; 144 142 int irq; 145 - unsigned long alarm; 143 + time64_t alarm; 144 + unsigned long flags; 146 145 147 146 struct clk_hw hw; 148 147 struct clk_hw *int_osc; ··· 370 363 CLK_OF_DECLARE_DRIVER(sun50i_h5_rtc_clk, "allwinner,sun50i-h5-rtc", 371 364 sun8i_h3_rtc_clk_init); 372 365 373 - static const struct sun6i_rtc_clk_data sun50i_h6_rtc_data = { 374 - .rc_osc_rate = 16000000, 375 - .fixed_prescaler = 32, 376 - .has_prescaler = 1, 377 - .has_out_clk = 1, 378 - .export_iosc = 1, 379 - .has_losc_en = 1, 380 - .has_auto_swt = 1, 381 - }; 382 - 383 - static void __init sun50i_h6_rtc_clk_init(struct device_node *node) 384 - { 385 - sun6i_rtc_clk_init(node, &sun50i_h6_rtc_data); 386 - } 387 - CLK_OF_DECLARE_DRIVER(sun50i_h6_rtc_clk, "allwinner,sun50i-h6-rtc", 388 - sun50i_h6_rtc_clk_init); 389 - 390 366 /* 391 367 * The R40 user manual is self-conflicting on whether the prescaler is 392 368 * fixed or configurable. The clock diagram shows it as fixed, but there ··· 457 467 } while ((date != readl(chip->base + SUN6I_RTC_YMD)) || 458 468 (time != readl(chip->base + SUN6I_RTC_HMS))); 459 469 470 + if (chip->flags & RTC_LINEAR_DAY) { 471 + /* 472 + * Newer chips store a linear day number, the manual 473 + * does not mandate any epoch base. The BSP driver uses 474 + * the UNIX epoch, let's just copy that, as it's the 475 + * easiest anyway. 476 + */ 477 + rtc_time64_to_tm((date & 0xffff) * SECS_PER_DAY, rtc_tm); 478 + } else { 479 + rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date); 480 + rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date) - 1; 481 + rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date); 482 + 483 + /* 484 + * switch from (data_year->min)-relative offset to 485 + * a (1900)-relative one 486 + */ 487 + rtc_tm->tm_year += SUN6I_YEAR_OFF; 488 + } 489 + 460 490 rtc_tm->tm_sec = SUN6I_TIME_GET_SEC_VALUE(time); 461 491 rtc_tm->tm_min = SUN6I_TIME_GET_MIN_VALUE(time); 462 492 rtc_tm->tm_hour = SUN6I_TIME_GET_HOUR_VALUE(time); 463 - 464 - rtc_tm->tm_mday = SUN6I_DATE_GET_DAY_VALUE(date); 465 - rtc_tm->tm_mon = SUN6I_DATE_GET_MON_VALUE(date); 466 - rtc_tm->tm_year = SUN6I_DATE_GET_YEAR_VALUE(date); 467 - 468 - rtc_tm->tm_mon -= 1; 469 - 470 - /* 471 - * switch from (data_year->min)-relative offset to 472 - * a (1900)-relative one 473 - */ 474 - rtc_tm->tm_year += SUN6I_YEAR_OFF; 475 493 476 494 return 0; 477 495 } ··· 508 510 struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); 509 511 struct rtc_time *alrm_tm = &wkalrm->time; 510 512 struct rtc_time tm_now; 511 - unsigned long time_now = 0; 512 - unsigned long time_set = 0; 513 - unsigned long time_gap = 0; 514 - int ret = 0; 515 - 516 - ret = sun6i_rtc_gettime(dev, &tm_now); 517 - if (ret < 0) { 518 - dev_err(dev, "Error in getting time\n"); 519 - return -EINVAL; 520 - } 513 + time64_t time_set; 514 + u32 counter_val, counter_val_hms; 515 + int ret; 521 516 522 517 time_set = rtc_tm_to_time64(alrm_tm); 523 - time_now = rtc_tm_to_time64(&tm_now); 524 - if (time_set <= time_now) { 525 - dev_err(dev, "Date to set in the past\n"); 526 - return -EINVAL; 527 - } 528 518 529 - time_gap = time_set - time_now; 519 + if (chip->flags & RTC_LINEAR_DAY) { 520 + /* 521 + * The alarm registers hold the actual alarm time, encoded 522 + * in the same way (linear day + HMS) as the current time. 523 + */ 524 + counter_val_hms = SUN6I_TIME_SET_SEC_VALUE(alrm_tm->tm_sec) | 525 + SUN6I_TIME_SET_MIN_VALUE(alrm_tm->tm_min) | 526 + SUN6I_TIME_SET_HOUR_VALUE(alrm_tm->tm_hour); 527 + /* The division will cut off the H:M:S part of alrm_tm. */ 528 + counter_val = div_u64(rtc_tm_to_time64(alrm_tm), SECS_PER_DAY); 529 + } else { 530 + /* The alarm register holds the number of seconds left. */ 531 + time64_t time_now; 530 532 531 - if (time_gap > U32_MAX) { 532 - dev_err(dev, "Date too far in the future\n"); 533 - return -EINVAL; 533 + ret = sun6i_rtc_gettime(dev, &tm_now); 534 + if (ret < 0) { 535 + dev_err(dev, "Error in getting time\n"); 536 + return -EINVAL; 537 + } 538 + 539 + time_now = rtc_tm_to_time64(&tm_now); 540 + if (time_set <= time_now) { 541 + dev_err(dev, "Date to set in the past\n"); 542 + return -EINVAL; 543 + } 544 + if ((time_set - time_now) > U32_MAX) { 545 + dev_err(dev, "Date too far in the future\n"); 546 + return -EINVAL; 547 + } 548 + 549 + counter_val = time_set - time_now; 534 550 } 535 551 536 552 sun6i_rtc_setaie(0, chip); 537 553 writel(0, chip->base + SUN6I_ALRM_COUNTER); 554 + if (chip->flags & RTC_LINEAR_DAY) 555 + writel(0, chip->base + SUN6I_ALRM_COUNTER_HMS); 538 556 usleep_range(100, 300); 539 557 540 - writel(time_gap, chip->base + SUN6I_ALRM_COUNTER); 558 + writel(counter_val, chip->base + SUN6I_ALRM_COUNTER); 559 + if (chip->flags & RTC_LINEAR_DAY) 560 + writel(counter_val_hms, chip->base + SUN6I_ALRM_COUNTER_HMS); 541 561 chip->alarm = time_set; 542 562 543 563 sun6i_rtc_setaie(wkalrm->enabled, chip); ··· 587 571 u32 date = 0; 588 572 u32 time = 0; 589 573 590 - rtc_tm->tm_year -= SUN6I_YEAR_OFF; 591 - rtc_tm->tm_mon += 1; 592 - 593 - date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | 594 - SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | 595 - SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); 596 - 597 - if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) 598 - date |= SUN6I_LEAP_SET_VALUE(1); 599 - 600 574 time = SUN6I_TIME_SET_SEC_VALUE(rtc_tm->tm_sec) | 601 575 SUN6I_TIME_SET_MIN_VALUE(rtc_tm->tm_min) | 602 576 SUN6I_TIME_SET_HOUR_VALUE(rtc_tm->tm_hour); 577 + 578 + if (chip->flags & RTC_LINEAR_DAY) { 579 + /* The division will cut off the H:M:S part of rtc_tm. */ 580 + date = div_u64(rtc_tm_to_time64(rtc_tm), SECS_PER_DAY); 581 + } else { 582 + rtc_tm->tm_year -= SUN6I_YEAR_OFF; 583 + rtc_tm->tm_mon += 1; 584 + 585 + date = SUN6I_DATE_SET_DAY_VALUE(rtc_tm->tm_mday) | 586 + SUN6I_DATE_SET_MON_VALUE(rtc_tm->tm_mon) | 587 + SUN6I_DATE_SET_YEAR_VALUE(rtc_tm->tm_year); 588 + 589 + if (is_leap_year(rtc_tm->tm_year + SUN6I_YEAR_MIN)) 590 + date |= SUN6I_LEAP_SET_VALUE(1); 591 + } 603 592 604 593 /* Check whether registers are writable */ 605 594 if (sun6i_rtc_wait(chip, SUN6I_LOSC_CTRL, ··· 689 668 static SIMPLE_DEV_PM_OPS(sun6i_rtc_pm_ops, 690 669 sun6i_rtc_suspend, sun6i_rtc_resume); 691 670 671 + static void sun6i_rtc_bus_clk_cleanup(void *data) 672 + { 673 + struct clk *bus_clk = data; 674 + 675 + clk_disable_unprepare(bus_clk); 676 + } 677 + 692 678 static int sun6i_rtc_probe(struct platform_device *pdev) 693 679 { 694 680 struct sun6i_rtc_dev *chip = sun6i_rtc; 681 + struct device *dev = &pdev->dev; 682 + struct clk *bus_clk; 695 683 int ret; 684 + 685 + bus_clk = devm_clk_get_optional(dev, "bus"); 686 + if (IS_ERR(bus_clk)) 687 + return PTR_ERR(bus_clk); 688 + 689 + if (bus_clk) { 690 + ret = clk_prepare_enable(bus_clk); 691 + if (ret) 692 + return ret; 693 + 694 + ret = devm_add_action_or_reset(dev, sun6i_rtc_bus_clk_cleanup, 695 + bus_clk); 696 + if (ret) 697 + return ret; 698 + } 696 699 697 700 if (!chip) { 698 701 chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); ··· 728 683 chip->base = devm_platform_ioremap_resource(pdev, 0); 729 684 if (IS_ERR(chip->base)) 730 685 return PTR_ERR(chip->base); 686 + 687 + if (IS_REACHABLE(CONFIG_SUN6I_RTC_CCU)) { 688 + ret = sun6i_rtc_ccu_probe(dev, chip->base); 689 + if (ret) 690 + return ret; 691 + } 731 692 } 732 693 733 694 platform_set_drvdata(pdev, chip); 695 + 696 + chip->flags = (unsigned long)of_device_get_match_data(&pdev->dev); 734 697 735 698 chip->irq = platform_get_irq(pdev, 0); 736 699 if (chip->irq < 0) ··· 786 733 return PTR_ERR(chip->rtc); 787 734 788 735 chip->rtc->ops = &sun6i_rtc_ops; 789 - chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */ 736 + if (chip->flags & RTC_LINEAR_DAY) 737 + chip->rtc->range_max = (65536 * SECS_PER_DAY) - 1; 738 + else 739 + chip->rtc->range_max = 2019686399LL; /* 2033-12-31 23:59:59 */ 790 740 791 741 ret = devm_rtc_register_device(chip->rtc); 792 742 if (ret) ··· 814 758 { .compatible = "allwinner,sun8i-v3-rtc" }, 815 759 { .compatible = "allwinner,sun50i-h5-rtc" }, 816 760 { .compatible = "allwinner,sun50i-h6-rtc" }, 761 + { .compatible = "allwinner,sun50i-h616-rtc", 762 + .data = (void *)RTC_LINEAR_DAY }, 817 763 { /* sentinel */ }, 818 764 }; 819 765 MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids);
+9 -2
drivers/rtc/rtc-wm8350.c
··· 432 432 return ret; 433 433 } 434 434 435 - wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, 435 + ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, 436 436 wm8350_rtc_update_handler, 0, 437 437 "RTC Seconds", wm8350); 438 + if (ret) 439 + return ret; 440 + 438 441 wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); 439 442 440 - wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, 443 + ret = wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, 441 444 wm8350_rtc_alarm_handler, 0, 442 445 "RTC Alarm", wm8350); 446 + if (ret) { 447 + wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350); 448 + return ret; 449 + } 443 450 444 451 return 0; 445 452 }
-2
drivers/rtc/rtc-xgene.c
··· 180 180 return ret; 181 181 } 182 182 183 - /* HW does not support update faster than 1 seconds */ 184 - pdata->rtc->uie_unsupported = 1; 185 183 pdata->rtc->ops = &xgene_rtc_ops; 186 184 pdata->rtc->range_max = U32_MAX; 187 185
+10
include/dt-bindings/clock/sun6i-rtc.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0+ or MIT) */ 2 + 3 + #ifndef _DT_BINDINGS_CLK_SUN6I_RTC_H_ 4 + #define _DT_BINDINGS_CLK_SUN6I_RTC_H_ 5 + 6 + #define CLK_OSC32K 0 7 + #define CLK_OSC32K_FANOUT 1 8 + #define CLK_IOSC 2 9 + 10 + #endif /* _DT_BINDINGS_CLK_SUN6I_RTC_H_ */
+2
include/linux/clk/sunxi-ng.h
··· 9 9 int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode); 10 10 int sunxi_ccu_get_mmc_timing_mode(struct clk *clk); 11 11 12 + int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg); 13 + 12 14 #endif
+2
include/linux/mc146818rtc.h
··· 86 86 /* 2 values for divider stage reset, others for "testing purposes only" */ 87 87 # define RTC_DIV_RESET1 0x60 88 88 # define RTC_DIV_RESET2 0x70 89 + /* In AMD BKDG bit 5 and 6 are reserved, bit 4 is for select dv0 bank */ 90 + # define RTC_AMD_BANK_SELECT 0x10 89 91 /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */ 90 92 # define RTC_RATE_SELECT 0x0F 91 93
-2
include/linux/rtc.h
··· 110 110 struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ 111 111 int pie_enabled; 112 112 struct work_struct irqwork; 113 - /* Some hardware can't support UIE mode */ 114 - int uie_unsupported; 115 113 116 114 /* 117 115 * This offset specifies the update timing of the RTC.
-1
include/linux/rtc/ds1685.h
··· 46 46 u32 regstep; 47 47 int irq_num; 48 48 bool bcd_mode; 49 - bool no_irq; 50 49 u8 (*read)(struct ds1685_priv *, int); 51 50 void (*write)(struct ds1685_priv *, int, u8); 52 51 void (*prepare_poweroff)(void);
+2 -1
include/uapi/linux/rtc.h
··· 133 133 #define RTC_FEATURE_UPDATE_INTERRUPT 4 134 134 #define RTC_FEATURE_CORRECTION 5 135 135 #define RTC_FEATURE_BACKUP_SWITCH_MODE 6 136 - #define RTC_FEATURE_CNT 7 136 + #define RTC_FEATURE_ALARM_WAKEUP_ONLY 7 137 + #define RTC_FEATURE_CNT 8 137 138 138 139 /* parameter list */ 139 140 #define RTC_PARAM_FEATURES 0