xref: /openbmc/linux/drivers/rtc/rtc-mt6397.c (revision 1802d0be)
11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2fc297911STianping Fang /*
3fc297911STianping Fang * Copyright (c) 2014-2015 MediaTek Inc.
4fc297911STianping Fang * Author: Tianping.Fang <tianping.fang@mediatek.com>
5fc297911STianping Fang */
6fc297911STianping Fang 
7fc297911STianping Fang #include <linux/delay.h>
8fc297911STianping Fang #include <linux/init.h>
9fc297911STianping Fang #include <linux/module.h>
10fc297911STianping Fang #include <linux/regmap.h>
11fc297911STianping Fang #include <linux/rtc.h>
12fc297911STianping Fang #include <linux/irqdomain.h>
13fc297911STianping Fang #include <linux/platform_device.h>
14fc297911STianping Fang #include <linux/of_address.h>
15fc297911STianping Fang #include <linux/of_irq.h>
16fc297911STianping Fang #include <linux/io.h>
17fc297911STianping Fang #include <linux/mfd/mt6397/core.h>
18fc297911STianping Fang 
19fc297911STianping Fang #define RTC_BBPU		0x0000
20fc297911STianping Fang #define RTC_BBPU_CBUSY		BIT(6)
21fc297911STianping Fang 
22fc297911STianping Fang #define RTC_WRTGR		0x003c
23fc297911STianping Fang 
24fc297911STianping Fang #define RTC_IRQ_STA		0x0002
25fc297911STianping Fang #define RTC_IRQ_STA_AL		BIT(0)
26fc297911STianping Fang #define RTC_IRQ_STA_LP		BIT(3)
27fc297911STianping Fang 
28fc297911STianping Fang #define RTC_IRQ_EN		0x0004
29fc297911STianping Fang #define RTC_IRQ_EN_AL		BIT(0)
30fc297911STianping Fang #define RTC_IRQ_EN_ONESHOT	BIT(2)
31fc297911STianping Fang #define RTC_IRQ_EN_LP		BIT(3)
32fc297911STianping Fang #define RTC_IRQ_EN_ONESHOT_AL	(RTC_IRQ_EN_ONESHOT | RTC_IRQ_EN_AL)
33fc297911STianping Fang 
34fc297911STianping Fang #define RTC_AL_MASK		0x0008
35fc297911STianping Fang #define RTC_AL_MASK_DOW		BIT(4)
36fc297911STianping Fang 
37fc297911STianping Fang #define RTC_TC_SEC		0x000a
38fc297911STianping Fang /* Min, Hour, Dom... register offset to RTC_TC_SEC */
39fc297911STianping Fang #define RTC_OFFSET_SEC		0
40fc297911STianping Fang #define RTC_OFFSET_MIN		1
41fc297911STianping Fang #define RTC_OFFSET_HOUR		2
42fc297911STianping Fang #define RTC_OFFSET_DOM		3
43fc297911STianping Fang #define RTC_OFFSET_DOW		4
44fc297911STianping Fang #define RTC_OFFSET_MTH		5
45fc297911STianping Fang #define RTC_OFFSET_YEAR		6
46fc297911STianping Fang #define RTC_OFFSET_COUNT	7
47fc297911STianping Fang 
48fc297911STianping Fang #define RTC_AL_SEC		0x0018
49fc297911STianping Fang 
50fc297911STianping Fang #define RTC_PDN2		0x002e
51fc297911STianping Fang #define RTC_PDN2_PWRON_ALARM	BIT(4)
52fc297911STianping Fang 
53fc297911STianping Fang #define RTC_MIN_YEAR		1968
54fc297911STianping Fang #define RTC_BASE_YEAR		1900
55fc297911STianping Fang #define RTC_NUM_YEARS		128
56fc297911STianping Fang #define RTC_MIN_YEAR_OFFSET	(RTC_MIN_YEAR - RTC_BASE_YEAR)
57fc297911STianping Fang 
58fc297911STianping Fang struct mt6397_rtc {
59fc297911STianping Fang 	struct device		*dev;
60fc297911STianping Fang 	struct rtc_device	*rtc_dev;
61fc297911STianping Fang 	struct mutex		lock;
62fc297911STianping Fang 	struct regmap		*regmap;
63fc297911STianping Fang 	int			irq;
64fc297911STianping Fang 	u32			addr_base;
65fc297911STianping Fang };
66fc297911STianping Fang 
67fc297911STianping Fang static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
68fc297911STianping Fang {
69fc297911STianping Fang 	unsigned long timeout = jiffies + HZ;
70fc297911STianping Fang 	int ret;
71fc297911STianping Fang 	u32 data;
72fc297911STianping Fang 
73fc297911STianping Fang 	ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);
74fc297911STianping Fang 	if (ret < 0)
75fc297911STianping Fang 		return ret;
76fc297911STianping Fang 
77fc297911STianping Fang 	while (1) {
78fc297911STianping Fang 		ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_BBPU,
79fc297911STianping Fang 				  &data);
80fc297911STianping Fang 		if (ret < 0)
81fc297911STianping Fang 			break;
82fc297911STianping Fang 		if (!(data & RTC_BBPU_CBUSY))
83fc297911STianping Fang 			break;
84fc297911STianping Fang 		if (time_after(jiffies, timeout)) {
85fc297911STianping Fang 			ret = -ETIMEDOUT;
86fc297911STianping Fang 			break;
87fc297911STianping Fang 		}
88fc297911STianping Fang 		cpu_relax();
89fc297911STianping Fang 	}
90fc297911STianping Fang 
91fc297911STianping Fang 	return ret;
92fc297911STianping Fang }
93fc297911STianping Fang 
94fc297911STianping Fang static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
95fc297911STianping Fang {
96fc297911STianping Fang 	struct mt6397_rtc *rtc = data;
97fc297911STianping Fang 	u32 irqsta, irqen;
98fc297911STianping Fang 	int ret;
99fc297911STianping Fang 
100fc297911STianping Fang 	ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_STA, &irqsta);
101fc297911STianping Fang 	if ((ret >= 0) && (irqsta & RTC_IRQ_STA_AL)) {
102fc297911STianping Fang 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
103fc297911STianping Fang 		irqen = irqsta & ~RTC_IRQ_EN_AL;
104fc297911STianping Fang 		mutex_lock(&rtc->lock);
105fc297911STianping Fang 		if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
106fc297911STianping Fang 				 irqen) < 0)
107fc297911STianping Fang 			mtk_rtc_write_trigger(rtc);
108fc297911STianping Fang 		mutex_unlock(&rtc->lock);
109fc297911STianping Fang 
110fc297911STianping Fang 		return IRQ_HANDLED;
111fc297911STianping Fang 	}
112fc297911STianping Fang 
113fc297911STianping Fang 	return IRQ_NONE;
114fc297911STianping Fang }
115fc297911STianping Fang 
116fc297911STianping Fang static int __mtk_rtc_read_time(struct mt6397_rtc *rtc,
117fc297911STianping Fang 			       struct rtc_time *tm, int *sec)
118fc297911STianping Fang {
119fc297911STianping Fang 	int ret;
120fc297911STianping Fang 	u16 data[RTC_OFFSET_COUNT];
121fc297911STianping Fang 
122fc297911STianping Fang 	mutex_lock(&rtc->lock);
123fc297911STianping Fang 	ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC,
124fc297911STianping Fang 			       data, RTC_OFFSET_COUNT);
125fc297911STianping Fang 	if (ret < 0)
126fc297911STianping Fang 		goto exit;
127fc297911STianping Fang 
128fc297911STianping Fang 	tm->tm_sec = data[RTC_OFFSET_SEC];
129fc297911STianping Fang 	tm->tm_min = data[RTC_OFFSET_MIN];
130fc297911STianping Fang 	tm->tm_hour = data[RTC_OFFSET_HOUR];
131fc297911STianping Fang 	tm->tm_mday = data[RTC_OFFSET_DOM];
132fc297911STianping Fang 	tm->tm_mon = data[RTC_OFFSET_MTH];
133fc297911STianping Fang 	tm->tm_year = data[RTC_OFFSET_YEAR];
134fc297911STianping Fang 
135fc297911STianping Fang 	ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_TC_SEC, sec);
136fc297911STianping Fang exit:
137fc297911STianping Fang 	mutex_unlock(&rtc->lock);
138fc297911STianping Fang 	return ret;
139fc297911STianping Fang }
140fc297911STianping Fang 
141fc297911STianping Fang static int mtk_rtc_read_time(struct device *dev, struct rtc_time *tm)
142fc297911STianping Fang {
143fc297911STianping Fang 	time64_t time;
144fc297911STianping Fang 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
14593939967SAlexandre Belloni 	int days, sec, ret;
146fc297911STianping Fang 
147fc297911STianping Fang 	do {
148fc297911STianping Fang 		ret = __mtk_rtc_read_time(rtc, tm, &sec);
149fc297911STianping Fang 		if (ret < 0)
150fc297911STianping Fang 			goto exit;
151fc297911STianping Fang 	} while (sec < tm->tm_sec);
152fc297911STianping Fang 
153fc297911STianping Fang 	/* HW register use 7 bits to store year data, minus
154fc297911STianping Fang 	 * RTC_MIN_YEAR_OFFSET before write year data to register, and plus
155fc297911STianping Fang 	 * RTC_MIN_YEAR_OFFSET back after read year from register
156fc297911STianping Fang 	 */
157fc297911STianping Fang 	tm->tm_year += RTC_MIN_YEAR_OFFSET;
158fc297911STianping Fang 
159fc297911STianping Fang 	/* HW register start mon from one, but tm_mon start from zero. */
160fc297911STianping Fang 	tm->tm_mon--;
161fc297911STianping Fang 	time = rtc_tm_to_time64(tm);
162fc297911STianping Fang 
163fc297911STianping Fang 	/* rtc_tm_to_time64 covert Gregorian date to seconds since
164fc297911STianping Fang 	 * 01-01-1970 00:00:00, and this date is Thursday.
165fc297911STianping Fang 	 */
16693939967SAlexandre Belloni 	days = div_s64(time, 86400);
16793939967SAlexandre Belloni 	tm->tm_wday = (days + 4) % 7;
168fc297911STianping Fang 
169fc297911STianping Fang exit:
170fc297911STianping Fang 	return ret;
171fc297911STianping Fang }
172fc297911STianping Fang 
173fc297911STianping Fang static int mtk_rtc_set_time(struct device *dev, struct rtc_time *tm)
174fc297911STianping Fang {
175fc297911STianping Fang 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
176fc297911STianping Fang 	int ret;
177fc297911STianping Fang 	u16 data[RTC_OFFSET_COUNT];
178fc297911STianping Fang 
179fc297911STianping Fang 	tm->tm_year -= RTC_MIN_YEAR_OFFSET;
180fc297911STianping Fang 	tm->tm_mon++;
181fc297911STianping Fang 
182fc297911STianping Fang 	data[RTC_OFFSET_SEC] = tm->tm_sec;
183fc297911STianping Fang 	data[RTC_OFFSET_MIN] = tm->tm_min;
184fc297911STianping Fang 	data[RTC_OFFSET_HOUR] = tm->tm_hour;
185fc297911STianping Fang 	data[RTC_OFFSET_DOM] = tm->tm_mday;
186fc297911STianping Fang 	data[RTC_OFFSET_MTH] = tm->tm_mon;
187fc297911STianping Fang 	data[RTC_OFFSET_YEAR] = tm->tm_year;
188fc297911STianping Fang 
189fc297911STianping Fang 	mutex_lock(&rtc->lock);
190fc297911STianping Fang 	ret = regmap_bulk_write(rtc->regmap, rtc->addr_base + RTC_TC_SEC,
191fc297911STianping Fang 				data, RTC_OFFSET_COUNT);
192fc297911STianping Fang 	if (ret < 0)
193fc297911STianping Fang 		goto exit;
194fc297911STianping Fang 
195fc297911STianping Fang 	/* Time register write to hardware after call trigger function */
196fc297911STianping Fang 	ret = mtk_rtc_write_trigger(rtc);
197fc297911STianping Fang 
198fc297911STianping Fang exit:
199fc297911STianping Fang 	mutex_unlock(&rtc->lock);
200fc297911STianping Fang 	return ret;
201fc297911STianping Fang }
202fc297911STianping Fang 
203fc297911STianping Fang static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
204fc297911STianping Fang {
205fc297911STianping Fang 	struct rtc_time *tm = &alm->time;
206fc297911STianping Fang 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
207fc297911STianping Fang 	u32 irqen, pdn2;
208fc297911STianping Fang 	int ret;
209fc297911STianping Fang 	u16 data[RTC_OFFSET_COUNT];
210fc297911STianping Fang 
211fc297911STianping Fang 	mutex_lock(&rtc->lock);
212fc297911STianping Fang 	ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_IRQ_EN, &irqen);
213fc297911STianping Fang 	if (ret < 0)
214fc297911STianping Fang 		goto err_exit;
215fc297911STianping Fang 	ret = regmap_read(rtc->regmap, rtc->addr_base + RTC_PDN2, &pdn2);
216fc297911STianping Fang 	if (ret < 0)
217fc297911STianping Fang 		goto err_exit;
218fc297911STianping Fang 
219fc297911STianping Fang 	ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
220fc297911STianping Fang 			       data, RTC_OFFSET_COUNT);
221fc297911STianping Fang 	if (ret < 0)
222fc297911STianping Fang 		goto err_exit;
223fc297911STianping Fang 
224fc297911STianping Fang 	alm->enabled = !!(irqen & RTC_IRQ_EN_AL);
225fc297911STianping Fang 	alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
226fc297911STianping Fang 	mutex_unlock(&rtc->lock);
227fc297911STianping Fang 
228fc297911STianping Fang 	tm->tm_sec = data[RTC_OFFSET_SEC];
229fc297911STianping Fang 	tm->tm_min = data[RTC_OFFSET_MIN];
230fc297911STianping Fang 	tm->tm_hour = data[RTC_OFFSET_HOUR];
231fc297911STianping Fang 	tm->tm_mday = data[RTC_OFFSET_DOM];
232fc297911STianping Fang 	tm->tm_mon = data[RTC_OFFSET_MTH];
233fc297911STianping Fang 	tm->tm_year = data[RTC_OFFSET_YEAR];
234fc297911STianping Fang 
235fc297911STianping Fang 	tm->tm_year += RTC_MIN_YEAR_OFFSET;
236fc297911STianping Fang 	tm->tm_mon--;
237fc297911STianping Fang 
238fc297911STianping Fang 	return 0;
239fc297911STianping Fang err_exit:
240fc297911STianping Fang 	mutex_unlock(&rtc->lock);
241fc297911STianping Fang 	return ret;
242fc297911STianping Fang }
243fc297911STianping Fang 
244fc297911STianping Fang static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
245fc297911STianping Fang {
246fc297911STianping Fang 	struct rtc_time *tm = &alm->time;
247fc297911STianping Fang 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
248fc297911STianping Fang 	int ret;
249fc297911STianping Fang 	u16 data[RTC_OFFSET_COUNT];
250fc297911STianping Fang 
251fc297911STianping Fang 	tm->tm_year -= RTC_MIN_YEAR_OFFSET;
252fc297911STianping Fang 	tm->tm_mon++;
253fc297911STianping Fang 
254fc297911STianping Fang 	data[RTC_OFFSET_SEC] = tm->tm_sec;
255fc297911STianping Fang 	data[RTC_OFFSET_MIN] = tm->tm_min;
256fc297911STianping Fang 	data[RTC_OFFSET_HOUR] = tm->tm_hour;
257fc297911STianping Fang 	data[RTC_OFFSET_DOM] = tm->tm_mday;
258fc297911STianping Fang 	data[RTC_OFFSET_MTH] = tm->tm_mon;
259fc297911STianping Fang 	data[RTC_OFFSET_YEAR] = tm->tm_year;
260fc297911STianping Fang 
261fc297911STianping Fang 	mutex_lock(&rtc->lock);
262fc297911STianping Fang 	if (alm->enabled) {
263fc297911STianping Fang 		ret = regmap_bulk_write(rtc->regmap,
264fc297911STianping Fang 					rtc->addr_base + RTC_AL_SEC,
265fc297911STianping Fang 					data, RTC_OFFSET_COUNT);
266fc297911STianping Fang 		if (ret < 0)
267fc297911STianping Fang 			goto exit;
268fc297911STianping Fang 		ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_AL_MASK,
269fc297911STianping Fang 				   RTC_AL_MASK_DOW);
270fc297911STianping Fang 		if (ret < 0)
271fc297911STianping Fang 			goto exit;
272fc297911STianping Fang 		ret = regmap_update_bits(rtc->regmap,
273fc297911STianping Fang 					 rtc->addr_base + RTC_IRQ_EN,
274fc297911STianping Fang 					 RTC_IRQ_EN_ONESHOT_AL,
275fc297911STianping Fang 					 RTC_IRQ_EN_ONESHOT_AL);
276fc297911STianping Fang 		if (ret < 0)
277fc297911STianping Fang 			goto exit;
278fc297911STianping Fang 	} else {
279fc297911STianping Fang 		ret = regmap_update_bits(rtc->regmap,
280fc297911STianping Fang 					 rtc->addr_base + RTC_IRQ_EN,
281fc297911STianping Fang 					 RTC_IRQ_EN_ONESHOT_AL, 0);
282fc297911STianping Fang 		if (ret < 0)
283fc297911STianping Fang 			goto exit;
284fc297911STianping Fang 	}
285fc297911STianping Fang 
286fc297911STianping Fang 	/* All alarm time register write to hardware after calling
287fc297911STianping Fang 	 * mtk_rtc_write_trigger. This can avoid race condition if alarm
288fc297911STianping Fang 	 * occur happen during writing alarm time register.
289fc297911STianping Fang 	 */
290fc297911STianping Fang 	ret = mtk_rtc_write_trigger(rtc);
291fc297911STianping Fang exit:
292fc297911STianping Fang 	mutex_unlock(&rtc->lock);
293fc297911STianping Fang 	return ret;
294fc297911STianping Fang }
295fc297911STianping Fang 
29634c7b3acSJulia Lawall static const struct rtc_class_ops mtk_rtc_ops = {
297fc297911STianping Fang 	.read_time  = mtk_rtc_read_time,
298fc297911STianping Fang 	.set_time   = mtk_rtc_set_time,
299fc297911STianping Fang 	.read_alarm = mtk_rtc_read_alarm,
300fc297911STianping Fang 	.set_alarm  = mtk_rtc_set_alarm,
301fc297911STianping Fang };
302fc297911STianping Fang 
303fc297911STianping Fang static int mtk_rtc_probe(struct platform_device *pdev)
304fc297911STianping Fang {
305fc297911STianping Fang 	struct resource *res;
306fc297911STianping Fang 	struct mt6397_chip *mt6397_chip = dev_get_drvdata(pdev->dev.parent);
307fc297911STianping Fang 	struct mt6397_rtc *rtc;
308fc297911STianping Fang 	int ret;
309fc297911STianping Fang 
310fc297911STianping Fang 	rtc = devm_kzalloc(&pdev->dev, sizeof(struct mt6397_rtc), GFP_KERNEL);
311fc297911STianping Fang 	if (!rtc)
312fc297911STianping Fang 		return -ENOMEM;
313fc297911STianping Fang 
314fc297911STianping Fang 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315fc297911STianping Fang 	rtc->addr_base = res->start;
316fc297911STianping Fang 
317e695d3a0SChen Zhong 	rtc->irq = platform_get_irq(pdev, 0);
318e695d3a0SChen Zhong 	if (rtc->irq < 0)
319e695d3a0SChen Zhong 		return rtc->irq;
320fc297911STianping Fang 
321fc297911STianping Fang 	rtc->regmap = mt6397_chip->regmap;
322fc297911STianping Fang 	rtc->dev = &pdev->dev;
323fc297911STianping Fang 	mutex_init(&rtc->lock);
324fc297911STianping Fang 
325fc297911STianping Fang 	platform_set_drvdata(pdev, rtc);
326fc297911STianping Fang 
327babab2f8SAlexandre Belloni 	rtc->rtc_dev = devm_rtc_allocate_device(rtc->dev);
328babab2f8SAlexandre Belloni 	if (IS_ERR(rtc->rtc_dev))
329babab2f8SAlexandre Belloni 		return PTR_ERR(rtc->rtc_dev);
330babab2f8SAlexandre Belloni 
331fc297911STianping Fang 	ret = request_threaded_irq(rtc->irq, NULL,
332fc297911STianping Fang 				   mtk_rtc_irq_handler_thread,
333fc297911STianping Fang 				   IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
334fc297911STianping Fang 				   "mt6397-rtc", rtc);
335fc297911STianping Fang 	if (ret) {
336fc297911STianping Fang 		dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
337fc297911STianping Fang 			rtc->irq, ret);
33824db953eSPi-Hsun Shih 		return ret;
339fc297911STianping Fang 	}
340fc297911STianping Fang 
341baeca449SWei-Ning Huang 	device_init_wakeup(&pdev->dev, 1);
342baeca449SWei-Ning Huang 
343babab2f8SAlexandre Belloni 	rtc->rtc_dev->ops = &mtk_rtc_ops;
344babab2f8SAlexandre Belloni 
345babab2f8SAlexandre Belloni 	ret = rtc_register_device(rtc->rtc_dev);
346babab2f8SAlexandre Belloni 	if (ret) {
347fc297911STianping Fang 		dev_err(&pdev->dev, "register rtc device failed\n");
348fc297911STianping Fang 		goto out_free_irq;
349fc297911STianping Fang 	}
350fc297911STianping Fang 
351fc297911STianping Fang 	return 0;
352fc297911STianping Fang 
353fc297911STianping Fang out_free_irq:
35424db953eSPi-Hsun Shih 	free_irq(rtc->irq, rtc);
355fc297911STianping Fang 	return ret;
356fc297911STianping Fang }
357fc297911STianping Fang 
358fc297911STianping Fang static int mtk_rtc_remove(struct platform_device *pdev)
359fc297911STianping Fang {
360fc297911STianping Fang 	struct mt6397_rtc *rtc = platform_get_drvdata(pdev);
361fc297911STianping Fang 
36224db953eSPi-Hsun Shih 	free_irq(rtc->irq, rtc);
363fc297911STianping Fang 
364fc297911STianping Fang 	return 0;
365fc297911STianping Fang }
366fc297911STianping Fang 
367d7f9777dSHenry Chen #ifdef CONFIG_PM_SLEEP
368d7f9777dSHenry Chen static int mt6397_rtc_suspend(struct device *dev)
369d7f9777dSHenry Chen {
370d7f9777dSHenry Chen 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
371d7f9777dSHenry Chen 
372d7f9777dSHenry Chen 	if (device_may_wakeup(dev))
373d7f9777dSHenry Chen 		enable_irq_wake(rtc->irq);
374d7f9777dSHenry Chen 
375d7f9777dSHenry Chen 	return 0;
376d7f9777dSHenry Chen }
377d7f9777dSHenry Chen 
378d7f9777dSHenry Chen static int mt6397_rtc_resume(struct device *dev)
379d7f9777dSHenry Chen {
380d7f9777dSHenry Chen 	struct mt6397_rtc *rtc = dev_get_drvdata(dev);
381d7f9777dSHenry Chen 
382d7f9777dSHenry Chen 	if (device_may_wakeup(dev))
383d7f9777dSHenry Chen 		disable_irq_wake(rtc->irq);
384d7f9777dSHenry Chen 
385d7f9777dSHenry Chen 	return 0;
386d7f9777dSHenry Chen }
387d7f9777dSHenry Chen #endif
388d7f9777dSHenry Chen 
389d7f9777dSHenry Chen static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
390d7f9777dSHenry Chen 			mt6397_rtc_resume);
391d7f9777dSHenry Chen 
392fc297911STianping Fang static const struct of_device_id mt6397_rtc_of_match[] = {
393fc297911STianping Fang 	{ .compatible = "mediatek,mt6397-rtc", },
394fc297911STianping Fang 	{ }
395fc297911STianping Fang };
39673798d5cSJavier Martinez Canillas MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
397fc297911STianping Fang 
398fc297911STianping Fang static struct platform_driver mtk_rtc_driver = {
399fc297911STianping Fang 	.driver = {
400fc297911STianping Fang 		.name = "mt6397-rtc",
401fc297911STianping Fang 		.of_match_table = mt6397_rtc_of_match,
402d7f9777dSHenry Chen 		.pm = &mt6397_pm_ops,
403fc297911STianping Fang 	},
404fc297911STianping Fang 	.probe	= mtk_rtc_probe,
405fc297911STianping Fang 	.remove = mtk_rtc_remove,
406fc297911STianping Fang };
407fc297911STianping Fang 
408fc297911STianping Fang module_platform_driver(mtk_rtc_driver);
409fc297911STianping Fang 
410fc297911STianping Fang MODULE_LICENSE("GPL v2");
411fc297911STianping Fang MODULE_AUTHOR("Tianping Fang <tianping.fang@mediatek.com>");
412fc297911STianping Fang MODULE_DESCRIPTION("RTC Driver for MediaTek MT6397 PMIC");
413