xref: /openbmc/linux/drivers/rtc/rtc-ti-k3.c (revision 48144c28)
1b09d6335SNishanth Menon // SPDX-License-Identifier: GPL-2.0
2b09d6335SNishanth Menon /*
3b09d6335SNishanth Menon  * Texas Instruments K3 RTC driver
4b09d6335SNishanth Menon  *
5b09d6335SNishanth Menon  * Copyright (C) 2021-2022 Texas Instruments Incorporated - https://www.ti.com/
6b09d6335SNishanth Menon  */
7b09d6335SNishanth Menon 
8b09d6335SNishanth Menon #include <linux/clk.h>
9b09d6335SNishanth Menon #include <linux/delay.h>
10b09d6335SNishanth Menon #include <linux/mod_devicetable.h>
11b09d6335SNishanth Menon #include <linux/module.h>
12*48144c28SRob Herring #include <linux/of.h>
13b09d6335SNishanth Menon #include <linux/platform_device.h>
141e2585b4SBryan Brattlof #include <linux/sys_soc.h>
15b09d6335SNishanth Menon #include <linux/property.h>
16b09d6335SNishanth Menon #include <linux/regmap.h>
17b09d6335SNishanth Menon #include <linux/rtc.h>
18b09d6335SNishanth Menon 
19b09d6335SNishanth Menon /* Registers */
20b09d6335SNishanth Menon #define REG_K3RTC_S_CNT_LSW		0x08
21b09d6335SNishanth Menon #define REG_K3RTC_S_CNT_MSW		0x0c
22b09d6335SNishanth Menon #define REG_K3RTC_COMP			0x10
23b09d6335SNishanth Menon #define REG_K3RTC_ON_OFF_S_CNT_LSW	0x20
24b09d6335SNishanth Menon #define REG_K3RTC_ON_OFF_S_CNT_MSW	0x24
25b09d6335SNishanth Menon #define REG_K3RTC_SCRATCH0		0x30
26b09d6335SNishanth Menon #define REG_K3RTC_SCRATCH7		0x4c
27b09d6335SNishanth Menon #define REG_K3RTC_GENERAL_CTL		0x50
28b09d6335SNishanth Menon #define REG_K3RTC_IRQSTATUS_RAW_SYS	0x54
29b09d6335SNishanth Menon #define REG_K3RTC_IRQSTATUS_SYS		0x58
30b09d6335SNishanth Menon #define REG_K3RTC_IRQENABLE_SET_SYS	0x5c
31b09d6335SNishanth Menon #define REG_K3RTC_IRQENABLE_CLR_SYS	0x60
32b09d6335SNishanth Menon #define REG_K3RTC_SYNCPEND		0x68
33b09d6335SNishanth Menon #define REG_K3RTC_KICK0			0x70
34b09d6335SNishanth Menon #define REG_K3RTC_KICK1			0x74
35b09d6335SNishanth Menon 
36b09d6335SNishanth Menon /* Freeze when lsw is read and unfreeze when msw is read */
37b09d6335SNishanth Menon #define K3RTC_CNT_FMODE_S_CNT_VALUE	(0x2 << 24)
38b09d6335SNishanth Menon 
39b09d6335SNishanth Menon /* Magic values for lock/unlock */
40b09d6335SNishanth Menon #define K3RTC_KICK0_UNLOCK_VALUE	0x83e70b13
41b09d6335SNishanth Menon #define K3RTC_KICK1_UNLOCK_VALUE	0x95a4f1e0
42b09d6335SNishanth Menon 
43b09d6335SNishanth Menon /* Multiplier for ppb conversions */
44b09d6335SNishanth Menon #define K3RTC_PPB_MULT			(1000000000LL)
45b09d6335SNishanth Menon /* Min and max values supported with 'offset' interface (swapped sign) */
46b09d6335SNishanth Menon #define K3RTC_MIN_OFFSET		(-277761)
47b09d6335SNishanth Menon #define K3RTC_MAX_OFFSET		(277778)
48b09d6335SNishanth Menon 
49b09d6335SNishanth Menon static const struct regmap_config ti_k3_rtc_regmap_config = {
50b09d6335SNishanth Menon 	.name = "peripheral-registers",
51b09d6335SNishanth Menon 	.reg_bits = 32,
52b09d6335SNishanth Menon 	.val_bits = 32,
53b09d6335SNishanth Menon 	.reg_stride = 4,
54b09d6335SNishanth Menon 	.max_register = REG_K3RTC_KICK1,
55b09d6335SNishanth Menon };
56b09d6335SNishanth Menon 
57b09d6335SNishanth Menon enum ti_k3_rtc_fields {
58b09d6335SNishanth Menon 	K3RTC_KICK0,
59b09d6335SNishanth Menon 	K3RTC_KICK1,
60b09d6335SNishanth Menon 	K3RTC_S_CNT_LSW,
61b09d6335SNishanth Menon 	K3RTC_S_CNT_MSW,
62b09d6335SNishanth Menon 	K3RTC_O32K_OSC_DEP_EN,
63b09d6335SNishanth Menon 	K3RTC_UNLOCK,
64b09d6335SNishanth Menon 	K3RTC_CNT_FMODE,
65b09d6335SNishanth Menon 	K3RTC_PEND,
66b09d6335SNishanth Menon 	K3RTC_RELOAD_FROM_BBD,
67b09d6335SNishanth Menon 	K3RTC_COMP,
68b09d6335SNishanth Menon 
69b09d6335SNishanth Menon 	K3RTC_ALM_S_CNT_LSW,
70b09d6335SNishanth Menon 	K3RTC_ALM_S_CNT_MSW,
71b09d6335SNishanth Menon 	K3RTC_IRQ_STATUS_RAW,
72b09d6335SNishanth Menon 	K3RTC_IRQ_STATUS,
73b09d6335SNishanth Menon 	K3RTC_IRQ_ENABLE_SET,
74b09d6335SNishanth Menon 	K3RTC_IRQ_ENABLE_CLR,
75b09d6335SNishanth Menon 
76b09d6335SNishanth Menon 	K3RTC_IRQ_STATUS_ALT,
77b09d6335SNishanth Menon 	K3RTC_IRQ_ENABLE_CLR_ALT,
78b09d6335SNishanth Menon 
79b09d6335SNishanth Menon 	K3_RTC_MAX_FIELDS
80b09d6335SNishanth Menon };
81b09d6335SNishanth Menon 
82b09d6335SNishanth Menon static const struct reg_field ti_rtc_reg_fields[] = {
83b09d6335SNishanth Menon 	[K3RTC_KICK0] = REG_FIELD(REG_K3RTC_KICK0, 0, 31),
84b09d6335SNishanth Menon 	[K3RTC_KICK1] = REG_FIELD(REG_K3RTC_KICK1, 0, 31),
85b09d6335SNishanth Menon 	[K3RTC_S_CNT_LSW] = REG_FIELD(REG_K3RTC_S_CNT_LSW, 0, 31),
86b09d6335SNishanth Menon 	[K3RTC_S_CNT_MSW] = REG_FIELD(REG_K3RTC_S_CNT_MSW, 0, 15),
87b09d6335SNishanth Menon 	[K3RTC_O32K_OSC_DEP_EN] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 21, 21),
88b09d6335SNishanth Menon 	[K3RTC_UNLOCK] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 23, 23),
89b09d6335SNishanth Menon 	[K3RTC_CNT_FMODE] = REG_FIELD(REG_K3RTC_GENERAL_CTL, 24, 25),
90b09d6335SNishanth Menon 	[K3RTC_PEND] = REG_FIELD(REG_K3RTC_SYNCPEND, 0, 1),
91b09d6335SNishanth Menon 	[K3RTC_RELOAD_FROM_BBD] = REG_FIELD(REG_K3RTC_SYNCPEND, 31, 31),
92b09d6335SNishanth Menon 	[K3RTC_COMP] = REG_FIELD(REG_K3RTC_COMP, 0, 31),
93b09d6335SNishanth Menon 
94b09d6335SNishanth Menon 	/* We use on to off as alarm trigger */
95b09d6335SNishanth Menon 	[K3RTC_ALM_S_CNT_LSW] = REG_FIELD(REG_K3RTC_ON_OFF_S_CNT_LSW, 0, 31),
96b09d6335SNishanth Menon 	[K3RTC_ALM_S_CNT_MSW] = REG_FIELD(REG_K3RTC_ON_OFF_S_CNT_MSW, 0, 15),
97b09d6335SNishanth Menon 	[K3RTC_IRQ_STATUS_RAW] = REG_FIELD(REG_K3RTC_IRQSTATUS_RAW_SYS, 0, 0),
98b09d6335SNishanth Menon 	[K3RTC_IRQ_STATUS] = REG_FIELD(REG_K3RTC_IRQSTATUS_SYS, 0, 0),
99b09d6335SNishanth Menon 	[K3RTC_IRQ_ENABLE_SET] = REG_FIELD(REG_K3RTC_IRQENABLE_SET_SYS, 0, 0),
100b09d6335SNishanth Menon 	[K3RTC_IRQ_ENABLE_CLR] = REG_FIELD(REG_K3RTC_IRQENABLE_CLR_SYS, 0, 0),
101b09d6335SNishanth Menon 	/* Off to on is alternate */
102b09d6335SNishanth Menon 	[K3RTC_IRQ_STATUS_ALT] = REG_FIELD(REG_K3RTC_IRQSTATUS_SYS, 1, 1),
103b09d6335SNishanth Menon 	[K3RTC_IRQ_ENABLE_CLR_ALT] = REG_FIELD(REG_K3RTC_IRQENABLE_CLR_SYS, 1, 1),
104b09d6335SNishanth Menon };
105b09d6335SNishanth Menon 
106b09d6335SNishanth Menon /**
107b09d6335SNishanth Menon  * struct ti_k3_rtc - Private data for ti-k3-rtc
108b09d6335SNishanth Menon  * @irq:		IRQ
109b09d6335SNishanth Menon  * @sync_timeout_us:	data sync timeout period in uSec
110b09d6335SNishanth Menon  * @rate_32k:		32k clock rate in Hz
111b09d6335SNishanth Menon  * @rtc_dev:		rtc device
112b09d6335SNishanth Menon  * @regmap:		rtc mmio regmap
113b09d6335SNishanth Menon  * @r_fields:		rtc register fields
114b09d6335SNishanth Menon  */
115b09d6335SNishanth Menon struct ti_k3_rtc {
116b09d6335SNishanth Menon 	unsigned int irq;
117b09d6335SNishanth Menon 	u32 sync_timeout_us;
118b09d6335SNishanth Menon 	unsigned long rate_32k;
119b09d6335SNishanth Menon 	struct rtc_device *rtc_dev;
120b09d6335SNishanth Menon 	struct regmap *regmap;
121b09d6335SNishanth Menon 	struct regmap_field *r_fields[K3_RTC_MAX_FIELDS];
122b09d6335SNishanth Menon };
123b09d6335SNishanth Menon 
k3rtc_field_read(struct ti_k3_rtc * priv,enum ti_k3_rtc_fields f)124b09d6335SNishanth Menon static int k3rtc_field_read(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f)
125b09d6335SNishanth Menon {
126b09d6335SNishanth Menon 	int ret;
127b09d6335SNishanth Menon 	int val;
128b09d6335SNishanth Menon 
129b09d6335SNishanth Menon 	ret = regmap_field_read(priv->r_fields[f], &val);
130b09d6335SNishanth Menon 	/*
131b09d6335SNishanth Menon 	 * We shouldn't be seeing regmap fail on us for mmio reads
132b09d6335SNishanth Menon 	 * This is possible if clock context fails, but that isn't the case for us
133b09d6335SNishanth Menon 	 */
134b09d6335SNishanth Menon 	if (WARN_ON_ONCE(ret))
135b09d6335SNishanth Menon 		return ret;
136b09d6335SNishanth Menon 	return val;
137b09d6335SNishanth Menon }
138b09d6335SNishanth Menon 
k3rtc_field_write(struct ti_k3_rtc * priv,enum ti_k3_rtc_fields f,u32 val)139b09d6335SNishanth Menon static void k3rtc_field_write(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f, u32 val)
140b09d6335SNishanth Menon {
141b09d6335SNishanth Menon 	regmap_field_write(priv->r_fields[f], val);
142b09d6335SNishanth Menon }
143b09d6335SNishanth Menon 
144b09d6335SNishanth Menon /**
145b09d6335SNishanth Menon  * k3rtc_fence  - Ensure a register sync took place between the two domains
146b09d6335SNishanth Menon  * @priv:      pointer to priv data
147b09d6335SNishanth Menon  *
148b09d6335SNishanth Menon  * Return: 0 if the sync took place, else returns -ETIMEDOUT
149b09d6335SNishanth Menon  */
k3rtc_fence(struct ti_k3_rtc * priv)150b09d6335SNishanth Menon static int k3rtc_fence(struct ti_k3_rtc *priv)
151b09d6335SNishanth Menon {
152b09d6335SNishanth Menon 	int ret;
153b09d6335SNishanth Menon 
154b09d6335SNishanth Menon 	ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_PEND], ret,
155b09d6335SNishanth Menon 					     !ret, 2, priv->sync_timeout_us);
156b09d6335SNishanth Menon 
157b09d6335SNishanth Menon 	return ret;
158b09d6335SNishanth Menon }
159b09d6335SNishanth Menon 
k3rtc_check_unlocked(struct ti_k3_rtc * priv)160b09d6335SNishanth Menon static inline int k3rtc_check_unlocked(struct ti_k3_rtc *priv)
161b09d6335SNishanth Menon {
162b09d6335SNishanth Menon 	int ret;
163b09d6335SNishanth Menon 
164b09d6335SNishanth Menon 	ret = k3rtc_field_read(priv, K3RTC_UNLOCK);
165b09d6335SNishanth Menon 	if (ret < 0)
166b09d6335SNishanth Menon 		return ret;
167b09d6335SNishanth Menon 
168b09d6335SNishanth Menon 	return (ret) ? 0 : 1;
169b09d6335SNishanth Menon }
170b09d6335SNishanth Menon 
k3rtc_unlock_rtc(struct ti_k3_rtc * priv)171b09d6335SNishanth Menon static int k3rtc_unlock_rtc(struct ti_k3_rtc *priv)
172b09d6335SNishanth Menon {
173b09d6335SNishanth Menon 	int ret;
174b09d6335SNishanth Menon 
175b09d6335SNishanth Menon 	ret = k3rtc_check_unlocked(priv);
176b09d6335SNishanth Menon 	if (!ret)
177b09d6335SNishanth Menon 		return ret;
178b09d6335SNishanth Menon 
179b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_KICK0, K3RTC_KICK0_UNLOCK_VALUE);
180b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_KICK1, K3RTC_KICK1_UNLOCK_VALUE);
181b09d6335SNishanth Menon 
182b09d6335SNishanth Menon 	/* Skip fence since we are going to check the unlock bit as fence */
183b09d6335SNishanth Menon 	ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_UNLOCK], ret,
184f2c5671aSBryan Brattlof 					     ret, 2, priv->sync_timeout_us);
185b09d6335SNishanth Menon 
186b09d6335SNishanth Menon 	return ret;
187b09d6335SNishanth Menon }
188b09d6335SNishanth Menon 
1891e2585b4SBryan Brattlof /*
1901e2585b4SBryan Brattlof  * This is the list of SoCs affected by TI's i2327 errata causing the RTC
1911e2585b4SBryan Brattlof  * state-machine to break if not unlocked fast enough during boot. These
1921e2585b4SBryan Brattlof  * SoCs must have the bootloader unlock this device very early in the
1931e2585b4SBryan Brattlof  * boot-flow before we (Linux) can use this device.
1941e2585b4SBryan Brattlof  */
1951e2585b4SBryan Brattlof static const struct soc_device_attribute has_erratum_i2327[] = {
1961e2585b4SBryan Brattlof 	{ .family = "AM62X", .revision = "SR1.0" },
1971e2585b4SBryan Brattlof 	{ /* sentinel */ }
1981e2585b4SBryan Brattlof };
1991e2585b4SBryan Brattlof 
k3rtc_configure(struct device * dev)200b09d6335SNishanth Menon static int k3rtc_configure(struct device *dev)
201b09d6335SNishanth Menon {
202b09d6335SNishanth Menon 	int ret;
203b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
204b09d6335SNishanth Menon 
205b09d6335SNishanth Menon 	/*
206b09d6335SNishanth Menon 	 * HWBUG: The compare state machine is broken if the RTC module
207b09d6335SNishanth Menon 	 * is NOT unlocked in under one second of boot - which is pretty long
208b09d6335SNishanth Menon 	 * time from the perspective of Linux driver (module load, u-boot
209b09d6335SNishanth Menon 	 * shell all can take much longer than this.
210b09d6335SNishanth Menon 	 *
211b09d6335SNishanth Menon 	 * In such occurrence, it is assumed that the RTC module is unusable
212b09d6335SNishanth Menon 	 */
2131e2585b4SBryan Brattlof 	if (soc_device_match(has_erratum_i2327)) {
214b09d6335SNishanth Menon 		ret = k3rtc_check_unlocked(priv);
215b09d6335SNishanth Menon 		/* If there is an error OR if we are locked, return error */
216b09d6335SNishanth Menon 		if (ret) {
217b09d6335SNishanth Menon 			dev_err(dev,
218b09d6335SNishanth Menon 				HW_ERR "Erratum i2327 unlock QUIRK! Cannot operate!!\n");
219b09d6335SNishanth Menon 			return -EFAULT;
220b09d6335SNishanth Menon 		}
221b09d6335SNishanth Menon 	} else {
222b09d6335SNishanth Menon 		/* May need to explicitly unlock first time */
223b09d6335SNishanth Menon 		ret = k3rtc_unlock_rtc(priv);
224b09d6335SNishanth Menon 		if (ret) {
225b09d6335SNishanth Menon 			dev_err(dev, "Failed to unlock(%d)!\n", ret);
226b09d6335SNishanth Menon 			return ret;
227b09d6335SNishanth Menon 		}
228b09d6335SNishanth Menon 	}
229b09d6335SNishanth Menon 
230b09d6335SNishanth Menon 	/* Enable Shadow register sync on 32k clock boundary */
231b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_O32K_OSC_DEP_EN, 0x1);
232b09d6335SNishanth Menon 
233b09d6335SNishanth Menon 	/*
234b09d6335SNishanth Menon 	 * Wait at least clock sync time before proceeding further programming.
235b09d6335SNishanth Menon 	 * This ensures that the 32k based sync is active.
236b09d6335SNishanth Menon 	 */
237b09d6335SNishanth Menon 	usleep_range(priv->sync_timeout_us, priv->sync_timeout_us + 5);
238b09d6335SNishanth Menon 
239b09d6335SNishanth Menon 	/* We need to ensure fence here to make sure sync here */
240b09d6335SNishanth Menon 	ret = k3rtc_fence(priv);
241b09d6335SNishanth Menon 	if (ret) {
242b09d6335SNishanth Menon 		dev_err(dev,
243b09d6335SNishanth Menon 			"Failed fence osc_dep enable(%d) - is 32k clk working?!\n", ret);
244b09d6335SNishanth Menon 		return ret;
245b09d6335SNishanth Menon 	}
246b09d6335SNishanth Menon 
247b09d6335SNishanth Menon 	/*
248b09d6335SNishanth Menon 	 * FMODE setting: Reading lower seconds will freeze value on higher
249b09d6335SNishanth Menon 	 * seconds. This also implies that we must *ALWAYS* read lower seconds
250b09d6335SNishanth Menon 	 * prior to reading higher seconds
251b09d6335SNishanth Menon 	 */
252b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_CNT_FMODE, K3RTC_CNT_FMODE_S_CNT_VALUE);
253b09d6335SNishanth Menon 
254b09d6335SNishanth Menon 	/* Clear any spurious IRQ sources if any */
255b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_IRQ_STATUS_ALT, 0x1);
256b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_IRQ_STATUS, 0x1);
257b09d6335SNishanth Menon 	/* Disable all IRQs */
258b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_IRQ_ENABLE_CLR_ALT, 0x1);
259b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_IRQ_ENABLE_CLR, 0x1);
260b09d6335SNishanth Menon 
261b09d6335SNishanth Menon 	/* And.. Let us Sync the writes in */
262b09d6335SNishanth Menon 	return k3rtc_fence(priv);
263b09d6335SNishanth Menon }
264b09d6335SNishanth Menon 
ti_k3_rtc_read_time(struct device * dev,struct rtc_time * tm)265b09d6335SNishanth Menon static int ti_k3_rtc_read_time(struct device *dev, struct rtc_time *tm)
266b09d6335SNishanth Menon {
267b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
268b09d6335SNishanth Menon 	u32 seconds_lo, seconds_hi;
269b09d6335SNishanth Menon 
270b09d6335SNishanth Menon 	seconds_lo = k3rtc_field_read(priv, K3RTC_S_CNT_LSW);
271b09d6335SNishanth Menon 	seconds_hi = k3rtc_field_read(priv, K3RTC_S_CNT_MSW);
272b09d6335SNishanth Menon 
273b09d6335SNishanth Menon 	rtc_time64_to_tm((((time64_t)seconds_hi) << 32) | (time64_t)seconds_lo, tm);
274b09d6335SNishanth Menon 
275b09d6335SNishanth Menon 	return 0;
276b09d6335SNishanth Menon }
277b09d6335SNishanth Menon 
ti_k3_rtc_set_time(struct device * dev,struct rtc_time * tm)278b09d6335SNishanth Menon static int ti_k3_rtc_set_time(struct device *dev, struct rtc_time *tm)
279b09d6335SNishanth Menon {
280b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
281b09d6335SNishanth Menon 	time64_t seconds;
282b09d6335SNishanth Menon 
283b09d6335SNishanth Menon 	seconds = rtc_tm_to_time64(tm);
284b09d6335SNishanth Menon 
285b09d6335SNishanth Menon 	/*
286b09d6335SNishanth Menon 	 * Read operation on LSW will freeze the RTC, so to update
287b09d6335SNishanth Menon 	 * the time, we cannot use field operations. Just write since the
288b09d6335SNishanth Menon 	 * reserved bits are ignored.
289b09d6335SNishanth Menon 	 */
290b09d6335SNishanth Menon 	regmap_write(priv->regmap, REG_K3RTC_S_CNT_LSW, seconds);
291b09d6335SNishanth Menon 	regmap_write(priv->regmap, REG_K3RTC_S_CNT_MSW, seconds >> 32);
292b09d6335SNishanth Menon 
293b09d6335SNishanth Menon 	return k3rtc_fence(priv);
294b09d6335SNishanth Menon }
295b09d6335SNishanth Menon 
ti_k3_rtc_alarm_irq_enable(struct device * dev,unsigned int enabled)296b09d6335SNishanth Menon static int ti_k3_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
297b09d6335SNishanth Menon {
298b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
299b09d6335SNishanth Menon 	u32 reg;
300b09d6335SNishanth Menon 	u32 offset = enabled ? K3RTC_IRQ_ENABLE_SET : K3RTC_IRQ_ENABLE_CLR;
301b09d6335SNishanth Menon 
302b09d6335SNishanth Menon 	reg = k3rtc_field_read(priv, K3RTC_IRQ_ENABLE_SET);
303b09d6335SNishanth Menon 	if ((enabled && reg) || (!enabled && !reg))
304b09d6335SNishanth Menon 		return 0;
305b09d6335SNishanth Menon 
306b09d6335SNishanth Menon 	k3rtc_field_write(priv, offset, 0x1);
307b09d6335SNishanth Menon 
308b09d6335SNishanth Menon 	/*
309b09d6335SNishanth Menon 	 * Ensure the write sync is through - NOTE: it should be OK to have
310b09d6335SNishanth Menon 	 * ISR to fire as we are checking sync (which should be done in a 32k
311b09d6335SNishanth Menon 	 * cycle or so).
312b09d6335SNishanth Menon 	 */
313b09d6335SNishanth Menon 	return k3rtc_fence(priv);
314b09d6335SNishanth Menon }
315b09d6335SNishanth Menon 
ti_k3_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alarm)316b09d6335SNishanth Menon static int ti_k3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
317b09d6335SNishanth Menon {
318b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
319b09d6335SNishanth Menon 	u32 seconds_lo, seconds_hi;
320b09d6335SNishanth Menon 
321b09d6335SNishanth Menon 	seconds_lo = k3rtc_field_read(priv, K3RTC_ALM_S_CNT_LSW);
322b09d6335SNishanth Menon 	seconds_hi = k3rtc_field_read(priv, K3RTC_ALM_S_CNT_MSW);
323b09d6335SNishanth Menon 
324b09d6335SNishanth Menon 	rtc_time64_to_tm((((time64_t)seconds_hi) << 32) | (time64_t)seconds_lo, &alarm->time);
325b09d6335SNishanth Menon 
326b09d6335SNishanth Menon 	alarm->enabled = k3rtc_field_read(priv, K3RTC_IRQ_ENABLE_SET);
327b09d6335SNishanth Menon 
328b09d6335SNishanth Menon 	return 0;
329b09d6335SNishanth Menon }
330b09d6335SNishanth Menon 
ti_k3_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alarm)331b09d6335SNishanth Menon static int ti_k3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
332b09d6335SNishanth Menon {
333b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
334b09d6335SNishanth Menon 	time64_t seconds;
335b09d6335SNishanth Menon 	int ret;
336b09d6335SNishanth Menon 
337b09d6335SNishanth Menon 	seconds = rtc_tm_to_time64(&alarm->time);
338b09d6335SNishanth Menon 
339b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_ALM_S_CNT_LSW, seconds);
340b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_ALM_S_CNT_MSW, (seconds >> 32));
341b09d6335SNishanth Menon 
342b09d6335SNishanth Menon 	/* Make sure the alarm time is synced in */
343b09d6335SNishanth Menon 	ret = k3rtc_fence(priv);
344b09d6335SNishanth Menon 	if (ret) {
345b09d6335SNishanth Menon 		dev_err(dev, "Failed to fence(%d)! Potential config issue?\n", ret);
346b09d6335SNishanth Menon 		return ret;
347b09d6335SNishanth Menon 	}
348b09d6335SNishanth Menon 
349b09d6335SNishanth Menon 	/* Alarm IRQ enable will do a sync */
350b09d6335SNishanth Menon 	return ti_k3_rtc_alarm_irq_enable(dev, alarm->enabled);
351b09d6335SNishanth Menon }
352b09d6335SNishanth Menon 
ti_k3_rtc_read_offset(struct device * dev,long * offset)353b09d6335SNishanth Menon static int ti_k3_rtc_read_offset(struct device *dev, long *offset)
354b09d6335SNishanth Menon {
355b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
356b09d6335SNishanth Menon 	u32 ticks_per_hr = priv->rate_32k * 3600;
357b09d6335SNishanth Menon 	int comp;
358b09d6335SNishanth Menon 	s64 tmp;
359b09d6335SNishanth Menon 
360b09d6335SNishanth Menon 	comp = k3rtc_field_read(priv, K3RTC_COMP);
361b09d6335SNishanth Menon 
362b09d6335SNishanth Menon 	/* Convert from RTC calibration register format to ppb format */
363b09d6335SNishanth Menon 	tmp = comp * (s64)K3RTC_PPB_MULT;
364b09d6335SNishanth Menon 	if (tmp < 0)
365b09d6335SNishanth Menon 		tmp -= ticks_per_hr / 2LL;
366b09d6335SNishanth Menon 	else
367b09d6335SNishanth Menon 		tmp += ticks_per_hr / 2LL;
368b09d6335SNishanth Menon 	tmp = div_s64(tmp, ticks_per_hr);
369b09d6335SNishanth Menon 
370b09d6335SNishanth Menon 	/* Offset value operates in negative way, so swap sign */
371b09d6335SNishanth Menon 	*offset = (long)-tmp;
372b09d6335SNishanth Menon 
373b09d6335SNishanth Menon 	return 0;
374b09d6335SNishanth Menon }
375b09d6335SNishanth Menon 
ti_k3_rtc_set_offset(struct device * dev,long offset)376b09d6335SNishanth Menon static int ti_k3_rtc_set_offset(struct device *dev, long offset)
377b09d6335SNishanth Menon {
378b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
379b09d6335SNishanth Menon 	u32 ticks_per_hr = priv->rate_32k * 3600;
380b09d6335SNishanth Menon 	int comp;
381b09d6335SNishanth Menon 	s64 tmp;
382b09d6335SNishanth Menon 
383b09d6335SNishanth Menon 	/* Make sure offset value is within supported range */
384b09d6335SNishanth Menon 	if (offset < K3RTC_MIN_OFFSET || offset > K3RTC_MAX_OFFSET)
385b09d6335SNishanth Menon 		return -ERANGE;
386b09d6335SNishanth Menon 
387b09d6335SNishanth Menon 	/* Convert from ppb format to RTC calibration register format */
388b09d6335SNishanth Menon 	tmp = offset * (s64)ticks_per_hr;
389b09d6335SNishanth Menon 	if (tmp < 0)
390b09d6335SNishanth Menon 		tmp -= K3RTC_PPB_MULT / 2LL;
391b09d6335SNishanth Menon 	else
392b09d6335SNishanth Menon 		tmp += K3RTC_PPB_MULT / 2LL;
393b09d6335SNishanth Menon 	tmp = div_s64(tmp, K3RTC_PPB_MULT);
394b09d6335SNishanth Menon 
395b09d6335SNishanth Menon 	/* Offset value operates in negative way, so swap sign */
396b09d6335SNishanth Menon 	comp = (int)-tmp;
397b09d6335SNishanth Menon 
398b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_COMP, comp);
399b09d6335SNishanth Menon 
400b09d6335SNishanth Menon 	return k3rtc_fence(priv);
401b09d6335SNishanth Menon }
402b09d6335SNishanth Menon 
ti_k3_rtc_interrupt(s32 irq,void * dev_id)403b09d6335SNishanth Menon static irqreturn_t ti_k3_rtc_interrupt(s32 irq, void *dev_id)
404b09d6335SNishanth Menon {
405b09d6335SNishanth Menon 	struct device *dev = dev_id;
406b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
407b09d6335SNishanth Menon 	u32 reg;
408b09d6335SNishanth Menon 	int ret;
409b09d6335SNishanth Menon 
410b09d6335SNishanth Menon 	/*
411b09d6335SNishanth Menon 	 * IRQ assertion can be very fast, however, the IRQ Status clear
412b09d6335SNishanth Menon 	 * de-assert depends on 32k clock edge in the 32k domain
413b09d6335SNishanth Menon 	 * If we clear the status prior to the first 32k clock edge,
414b09d6335SNishanth Menon 	 * the status bit is cleared, but the IRQ stays re-asserted.
415b09d6335SNishanth Menon 	 *
416b09d6335SNishanth Menon 	 * To prevent this condition, we need to wait for clock sync time.
417b09d6335SNishanth Menon 	 * We can either do that by polling the 32k observability signal for
418b09d6335SNishanth Menon 	 * a toggle OR we could just sleep and let the processor do other
419b09d6335SNishanth Menon 	 * stuff.
420b09d6335SNishanth Menon 	 */
421b09d6335SNishanth Menon 	usleep_range(priv->sync_timeout_us, priv->sync_timeout_us + 2);
422b09d6335SNishanth Menon 
423b09d6335SNishanth Menon 	/* Lets make sure that this is a valid interrupt */
424b09d6335SNishanth Menon 	reg = k3rtc_field_read(priv, K3RTC_IRQ_STATUS);
425b09d6335SNishanth Menon 
426b09d6335SNishanth Menon 	if (!reg) {
427b09d6335SNishanth Menon 		u32 raw = k3rtc_field_read(priv, K3RTC_IRQ_STATUS_RAW);
428b09d6335SNishanth Menon 
429b09d6335SNishanth Menon 		dev_err(dev,
430b09d6335SNishanth Menon 			HW_ERR
431b09d6335SNishanth Menon 			"Erratum i2327/IRQ trig: status: 0x%08x / 0x%08x\n", reg, raw);
432b09d6335SNishanth Menon 		return IRQ_NONE;
433b09d6335SNishanth Menon 	}
434b09d6335SNishanth Menon 
435b09d6335SNishanth Menon 	/*
436b09d6335SNishanth Menon 	 * Write 1 to clear status reg
437b09d6335SNishanth Menon 	 * We cannot use a field operation here due to a potential race between
438b09d6335SNishanth Menon 	 * 32k domain and vbus domain.
439b09d6335SNishanth Menon 	 */
440b09d6335SNishanth Menon 	regmap_write(priv->regmap, REG_K3RTC_IRQSTATUS_SYS, 0x1);
441b09d6335SNishanth Menon 
442b09d6335SNishanth Menon 	/* Sync the write in */
443b09d6335SNishanth Menon 	ret = k3rtc_fence(priv);
444b09d6335SNishanth Menon 	if (ret) {
445b09d6335SNishanth Menon 		dev_err(dev, "Failed to fence irq status clr(%d)!\n", ret);
446b09d6335SNishanth Menon 		return IRQ_NONE;
447b09d6335SNishanth Menon 	}
448b09d6335SNishanth Menon 
449b09d6335SNishanth Menon 	/*
450b09d6335SNishanth Menon 	 * Force the 32k status to be reloaded back in to ensure status is
451b09d6335SNishanth Menon 	 * reflected back correctly.
452b09d6335SNishanth Menon 	 */
453b09d6335SNishanth Menon 	k3rtc_field_write(priv, K3RTC_RELOAD_FROM_BBD, 0x1);
454b09d6335SNishanth Menon 
455b09d6335SNishanth Menon 	/* Ensure the write sync is through */
456b09d6335SNishanth Menon 	ret = k3rtc_fence(priv);
457b09d6335SNishanth Menon 	if (ret) {
458b09d6335SNishanth Menon 		dev_err(dev, "Failed to fence reload from bbd(%d)!\n", ret);
459b09d6335SNishanth Menon 		return IRQ_NONE;
460b09d6335SNishanth Menon 	}
461b09d6335SNishanth Menon 
462b09d6335SNishanth Menon 	/* Now we ensure that the status bit is cleared */
463b09d6335SNishanth Menon 	ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_IRQ_STATUS],
464b09d6335SNishanth Menon 					     ret, !ret, 2, priv->sync_timeout_us);
465b09d6335SNishanth Menon 	if (ret) {
466b09d6335SNishanth Menon 		dev_err(dev, "Time out waiting for status clear\n");
467b09d6335SNishanth Menon 		return IRQ_NONE;
468b09d6335SNishanth Menon 	}
469b09d6335SNishanth Menon 
470b09d6335SNishanth Menon 	/* Notify RTC core on event */
471b09d6335SNishanth Menon 	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
472b09d6335SNishanth Menon 
473b09d6335SNishanth Menon 	return IRQ_HANDLED;
474b09d6335SNishanth Menon }
475b09d6335SNishanth Menon 
476b09d6335SNishanth Menon static const struct rtc_class_ops ti_k3_rtc_ops = {
477b09d6335SNishanth Menon 	.read_time = ti_k3_rtc_read_time,
478b09d6335SNishanth Menon 	.set_time = ti_k3_rtc_set_time,
479b09d6335SNishanth Menon 	.read_alarm = ti_k3_rtc_read_alarm,
480b09d6335SNishanth Menon 	.set_alarm = ti_k3_rtc_set_alarm,
481b09d6335SNishanth Menon 	.read_offset = ti_k3_rtc_read_offset,
482b09d6335SNishanth Menon 	.set_offset = ti_k3_rtc_set_offset,
483b09d6335SNishanth Menon 	.alarm_irq_enable = ti_k3_rtc_alarm_irq_enable,
484b09d6335SNishanth Menon };
485b09d6335SNishanth Menon 
ti_k3_rtc_scratch_read(void * priv_data,unsigned int offset,void * val,size_t bytes)486b09d6335SNishanth Menon static int ti_k3_rtc_scratch_read(void *priv_data, unsigned int offset,
487b09d6335SNishanth Menon 				  void *val, size_t bytes)
488b09d6335SNishanth Menon {
489b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = (struct ti_k3_rtc *)priv_data;
490b09d6335SNishanth Menon 
491b09d6335SNishanth Menon 	return regmap_bulk_read(priv->regmap, REG_K3RTC_SCRATCH0 + offset, val, bytes / 4);
492b09d6335SNishanth Menon }
493b09d6335SNishanth Menon 
ti_k3_rtc_scratch_write(void * priv_data,unsigned int offset,void * val,size_t bytes)494b09d6335SNishanth Menon static int ti_k3_rtc_scratch_write(void *priv_data, unsigned int offset,
495b09d6335SNishanth Menon 				   void *val, size_t bytes)
496b09d6335SNishanth Menon {
497b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = (struct ti_k3_rtc *)priv_data;
498b09d6335SNishanth Menon 	int ret;
499b09d6335SNishanth Menon 
500b09d6335SNishanth Menon 	ret = regmap_bulk_write(priv->regmap, REG_K3RTC_SCRATCH0 + offset, val, bytes / 4);
501b09d6335SNishanth Menon 	if (ret)
502b09d6335SNishanth Menon 		return ret;
503b09d6335SNishanth Menon 
504b09d6335SNishanth Menon 	return k3rtc_fence(priv);
505b09d6335SNishanth Menon }
506b09d6335SNishanth Menon 
507b09d6335SNishanth Menon static struct nvmem_config ti_k3_rtc_nvmem_config = {
508b09d6335SNishanth Menon 	.name = "ti_k3_rtc_scratch",
509b09d6335SNishanth Menon 	.word_size = 4,
510b09d6335SNishanth Menon 	.stride = 4,
511b09d6335SNishanth Menon 	.size = REG_K3RTC_SCRATCH7 - REG_K3RTC_SCRATCH0 + 4,
512b09d6335SNishanth Menon 	.reg_read = ti_k3_rtc_scratch_read,
513b09d6335SNishanth Menon 	.reg_write = ti_k3_rtc_scratch_write,
514b09d6335SNishanth Menon };
515b09d6335SNishanth Menon 
k3rtc_get_32kclk(struct device * dev,struct ti_k3_rtc * priv)516b09d6335SNishanth Menon static int k3rtc_get_32kclk(struct device *dev, struct ti_k3_rtc *priv)
517b09d6335SNishanth Menon {
518b09d6335SNishanth Menon 	struct clk *clk;
519b09d6335SNishanth Menon 
5208f08553eSChristophe JAILLET 	clk = devm_clk_get_enabled(dev, "osc32k");
521b09d6335SNishanth Menon 	if (IS_ERR(clk))
522b09d6335SNishanth Menon 		return PTR_ERR(clk);
523b09d6335SNishanth Menon 
524b09d6335SNishanth Menon 	priv->rate_32k = clk_get_rate(clk);
525b09d6335SNishanth Menon 
526b09d6335SNishanth Menon 	/* Make sure we are exact 32k clock. Else, try to compensate delay */
527b09d6335SNishanth Menon 	if (priv->rate_32k != 32768)
528b09d6335SNishanth Menon 		dev_warn(dev, "Clock rate %ld is not 32768! Could misbehave!\n",
529b09d6335SNishanth Menon 			 priv->rate_32k);
530b09d6335SNishanth Menon 
531b09d6335SNishanth Menon 	/*
532b09d6335SNishanth Menon 	 * Sync timeout should be two 32k clk sync cycles = ~61uS. We double
533b09d6335SNishanth Menon 	 * it to comprehend intermediate bus segment and cpu frequency
534b09d6335SNishanth Menon 	 * deltas
535b09d6335SNishanth Menon 	 */
536b09d6335SNishanth Menon 	priv->sync_timeout_us = (u32)(DIV_ROUND_UP_ULL(1000000, priv->rate_32k) * 4);
537b09d6335SNishanth Menon 
5388f08553eSChristophe JAILLET 	return 0;
539b09d6335SNishanth Menon }
540b09d6335SNishanth Menon 
k3rtc_get_vbusclk(struct device * dev,struct ti_k3_rtc * priv)541b09d6335SNishanth Menon static int k3rtc_get_vbusclk(struct device *dev, struct ti_k3_rtc *priv)
542b09d6335SNishanth Menon {
543b09d6335SNishanth Menon 	struct clk *clk;
544b09d6335SNishanth Menon 
545b09d6335SNishanth Menon 	/* Note: VBUS isn't a context clock, it is needed for hardware operation */
5468f08553eSChristophe JAILLET 	clk = devm_clk_get_enabled(dev, "vbus");
547b09d6335SNishanth Menon 	if (IS_ERR(clk))
548b09d6335SNishanth Menon 		return PTR_ERR(clk);
549b09d6335SNishanth Menon 
5508f08553eSChristophe JAILLET 	return 0;
551b09d6335SNishanth Menon }
552b09d6335SNishanth Menon 
ti_k3_rtc_probe(struct platform_device * pdev)553b09d6335SNishanth Menon static int ti_k3_rtc_probe(struct platform_device *pdev)
554b09d6335SNishanth Menon {
555b09d6335SNishanth Menon 	struct device *dev = &pdev->dev;
556b09d6335SNishanth Menon 	struct ti_k3_rtc *priv;
557b09d6335SNishanth Menon 	void __iomem *rtc_base;
558b09d6335SNishanth Menon 	int ret;
559b09d6335SNishanth Menon 
560b09d6335SNishanth Menon 	priv = devm_kzalloc(dev, sizeof(struct ti_k3_rtc), GFP_KERNEL);
561b09d6335SNishanth Menon 	if (!priv)
562b09d6335SNishanth Menon 		return -ENOMEM;
563b09d6335SNishanth Menon 
564b09d6335SNishanth Menon 	rtc_base = devm_platform_ioremap_resource(pdev, 0);
565b09d6335SNishanth Menon 	if (IS_ERR(rtc_base))
566b09d6335SNishanth Menon 		return PTR_ERR(rtc_base);
567b09d6335SNishanth Menon 
568b09d6335SNishanth Menon 	priv->regmap = devm_regmap_init_mmio(dev, rtc_base, &ti_k3_rtc_regmap_config);
569b09d6335SNishanth Menon 	if (IS_ERR(priv->regmap))
570b09d6335SNishanth Menon 		return PTR_ERR(priv->regmap);
571b09d6335SNishanth Menon 
572b09d6335SNishanth Menon 	ret = devm_regmap_field_bulk_alloc(dev, priv->regmap, priv->r_fields,
573b09d6335SNishanth Menon 					   ti_rtc_reg_fields, K3_RTC_MAX_FIELDS);
574b09d6335SNishanth Menon 	if (ret)
575b09d6335SNishanth Menon 		return ret;
576b09d6335SNishanth Menon 
577b09d6335SNishanth Menon 	ret = k3rtc_get_32kclk(dev, priv);
578b09d6335SNishanth Menon 	if (ret)
579b09d6335SNishanth Menon 		return ret;
580b09d6335SNishanth Menon 	ret = k3rtc_get_vbusclk(dev, priv);
581b09d6335SNishanth Menon 	if (ret)
582b09d6335SNishanth Menon 		return ret;
583b09d6335SNishanth Menon 
584b09d6335SNishanth Menon 	ret = platform_get_irq(pdev, 0);
585b09d6335SNishanth Menon 	if (ret < 0)
586b09d6335SNishanth Menon 		return ret;
587b09d6335SNishanth Menon 	priv->irq = (unsigned int)ret;
588b09d6335SNishanth Menon 
589b09d6335SNishanth Menon 	priv->rtc_dev = devm_rtc_allocate_device(dev);
590b09d6335SNishanth Menon 	if (IS_ERR(priv->rtc_dev))
591b09d6335SNishanth Menon 		return PTR_ERR(priv->rtc_dev);
592b09d6335SNishanth Menon 
593b09d6335SNishanth Menon 	priv->rtc_dev->ops = &ti_k3_rtc_ops;
594b09d6335SNishanth Menon 	priv->rtc_dev->range_max = (1ULL << 48) - 1;	/* 48Bit seconds */
595b09d6335SNishanth Menon 	ti_k3_rtc_nvmem_config.priv = priv;
596b09d6335SNishanth Menon 
597b09d6335SNishanth Menon 	ret = devm_request_threaded_irq(dev, priv->irq, NULL,
598b09d6335SNishanth Menon 					ti_k3_rtc_interrupt,
599b09d6335SNishanth Menon 					IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
600b09d6335SNishanth Menon 					dev_name(dev), dev);
601b09d6335SNishanth Menon 	if (ret) {
602b09d6335SNishanth Menon 		dev_err(dev, "Could not request IRQ: %d\n", ret);
603b09d6335SNishanth Menon 		return ret;
604b09d6335SNishanth Menon 	}
605b09d6335SNishanth Menon 
606b09d6335SNishanth Menon 	platform_set_drvdata(pdev, priv);
607b09d6335SNishanth Menon 
608b09d6335SNishanth Menon 	ret = k3rtc_configure(dev);
609b09d6335SNishanth Menon 	if (ret)
610b09d6335SNishanth Menon 		return ret;
611b09d6335SNishanth Menon 
612b09d6335SNishanth Menon 	if (device_property_present(dev, "wakeup-source"))
613b09d6335SNishanth Menon 		device_init_wakeup(dev, true);
614b09d6335SNishanth Menon 	else
615b09d6335SNishanth Menon 		device_set_wakeup_capable(dev, true);
616b09d6335SNishanth Menon 
617b09d6335SNishanth Menon 	ret = devm_rtc_register_device(priv->rtc_dev);
618b09d6335SNishanth Menon 	if (ret)
619b09d6335SNishanth Menon 		return ret;
620b09d6335SNishanth Menon 
621b09d6335SNishanth Menon 	return devm_rtc_nvmem_register(priv->rtc_dev, &ti_k3_rtc_nvmem_config);
622b09d6335SNishanth Menon }
623b09d6335SNishanth Menon 
624b09d6335SNishanth Menon static const struct of_device_id ti_k3_rtc_of_match_table[] = {
6251e2585b4SBryan Brattlof 	{.compatible = "ti,am62-rtc" },
626b09d6335SNishanth Menon 	{}
627b09d6335SNishanth Menon };
628b09d6335SNishanth Menon MODULE_DEVICE_TABLE(of, ti_k3_rtc_of_match_table);
629b09d6335SNishanth Menon 
ti_k3_rtc_suspend(struct device * dev)630b09d6335SNishanth Menon static int __maybe_unused ti_k3_rtc_suspend(struct device *dev)
631b09d6335SNishanth Menon {
632b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
633b09d6335SNishanth Menon 
634b09d6335SNishanth Menon 	if (device_may_wakeup(dev))
635d31d7300SDhruva Gole 		return enable_irq_wake(priv->irq);
636d31d7300SDhruva Gole 
637b09d6335SNishanth Menon 	return 0;
638b09d6335SNishanth Menon }
639b09d6335SNishanth Menon 
ti_k3_rtc_resume(struct device * dev)640b09d6335SNishanth Menon static int __maybe_unused ti_k3_rtc_resume(struct device *dev)
641b09d6335SNishanth Menon {
642b09d6335SNishanth Menon 	struct ti_k3_rtc *priv = dev_get_drvdata(dev);
643b09d6335SNishanth Menon 
644b09d6335SNishanth Menon 	if (device_may_wakeup(dev))
645b09d6335SNishanth Menon 		disable_irq_wake(priv->irq);
646b09d6335SNishanth Menon 	return 0;
647b09d6335SNishanth Menon }
648b09d6335SNishanth Menon 
649b09d6335SNishanth Menon static SIMPLE_DEV_PM_OPS(ti_k3_rtc_pm_ops, ti_k3_rtc_suspend, ti_k3_rtc_resume);
650b09d6335SNishanth Menon 
651b09d6335SNishanth Menon static struct platform_driver ti_k3_rtc_driver = {
652b09d6335SNishanth Menon 	.probe = ti_k3_rtc_probe,
653b09d6335SNishanth Menon 	.driver = {
654b09d6335SNishanth Menon 		   .name = "rtc-ti-k3",
655b09d6335SNishanth Menon 		   .of_match_table = ti_k3_rtc_of_match_table,
656b09d6335SNishanth Menon 		   .pm = &ti_k3_rtc_pm_ops,
657b09d6335SNishanth Menon 	},
658b09d6335SNishanth Menon };
659b09d6335SNishanth Menon module_platform_driver(ti_k3_rtc_driver);
660b09d6335SNishanth Menon 
661b09d6335SNishanth Menon MODULE_LICENSE("GPL");
662b09d6335SNishanth Menon MODULE_DESCRIPTION("TI K3 RTC driver");
663b09d6335SNishanth Menon MODULE_AUTHOR("Nishanth Menon");
664