xref: /OK3568_Linux_fs/kernel/drivers/rtc/rtc-mxc_v2.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Real Time Clock (RTC) Driver for i.MX53
4*4882a593Smuzhiyun  * Copyright (c) 2004-2011 Freescale Semiconductor, Inc.
5*4882a593Smuzhiyun  * Copyright (c) 2017 Beckhoff Automation GmbH & Co. KG
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/clk.h>
9*4882a593Smuzhiyun #include <linux/io.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
12*4882a593Smuzhiyun #include <linux/platform_device.h>
13*4882a593Smuzhiyun #include <linux/pm_wakeirq.h>
14*4882a593Smuzhiyun #include <linux/rtc.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #define SRTC_LPPDR_INIT       0x41736166	/* init for glitch detect */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define SRTC_LPCR_EN_LP       BIT(3)	/* lp enable */
19*4882a593Smuzhiyun #define SRTC_LPCR_WAE         BIT(4)	/* lp wakeup alarm enable */
20*4882a593Smuzhiyun #define SRTC_LPCR_ALP         BIT(7)	/* lp alarm flag */
21*4882a593Smuzhiyun #define SRTC_LPCR_NSA         BIT(11)	/* lp non secure access */
22*4882a593Smuzhiyun #define SRTC_LPCR_NVE         BIT(14)	/* lp non valid state exit bit */
23*4882a593Smuzhiyun #define SRTC_LPCR_IE          BIT(15)	/* lp init state exit bit */
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define SRTC_LPSR_ALP         BIT(3)	/* lp alarm flag */
26*4882a593Smuzhiyun #define SRTC_LPSR_NVES        BIT(14)	/* lp non-valid state exit status */
27*4882a593Smuzhiyun #define SRTC_LPSR_IES         BIT(15)	/* lp init state exit status */
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #define SRTC_LPSCMR	0x00	/* LP Secure Counter MSB Reg */
30*4882a593Smuzhiyun #define SRTC_LPSCLR	0x04	/* LP Secure Counter LSB Reg */
31*4882a593Smuzhiyun #define SRTC_LPSAR	0x08	/* LP Secure Alarm Reg */
32*4882a593Smuzhiyun #define SRTC_LPCR	0x10	/* LP Control Reg */
33*4882a593Smuzhiyun #define SRTC_LPSR	0x14	/* LP Status Reg */
34*4882a593Smuzhiyun #define SRTC_LPPDR	0x18	/* LP Power Supply Glitch Detector Reg */
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /* max. number of retries to read registers, 120 was max during test */
37*4882a593Smuzhiyun #define REG_READ_TIMEOUT 2000
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun struct mxc_rtc_data {
40*4882a593Smuzhiyun 	struct rtc_device *rtc;
41*4882a593Smuzhiyun 	void __iomem *ioaddr;
42*4882a593Smuzhiyun 	struct clk *clk;
43*4882a593Smuzhiyun 	spinlock_t lock; /* protects register access */
44*4882a593Smuzhiyun 	int irq;
45*4882a593Smuzhiyun };
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /*
48*4882a593Smuzhiyun  * This function does write synchronization for writes to the lp srtc block.
49*4882a593Smuzhiyun  * To take care of the asynchronous CKIL clock, all writes from the IP domain
50*4882a593Smuzhiyun  * will be synchronized to the CKIL domain.
51*4882a593Smuzhiyun  * The caller should hold the pdata->lock
52*4882a593Smuzhiyun  */
mxc_rtc_sync_lp_locked(struct device * dev,void __iomem * ioaddr)53*4882a593Smuzhiyun static void mxc_rtc_sync_lp_locked(struct device *dev, void __iomem *ioaddr)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun 	unsigned int i;
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	/* Wait for 3 CKIL cycles */
58*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
59*4882a593Smuzhiyun 		const u32 count = readl(ioaddr + SRTC_LPSCLR);
60*4882a593Smuzhiyun 		unsigned int timeout = REG_READ_TIMEOUT;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 		while ((readl(ioaddr + SRTC_LPSCLR)) == count) {
63*4882a593Smuzhiyun 			if (!--timeout) {
64*4882a593Smuzhiyun 				dev_err_once(dev, "SRTC_LPSCLR stuck! Check your hw.\n");
65*4882a593Smuzhiyun 				return;
66*4882a593Smuzhiyun 			}
67*4882a593Smuzhiyun 		}
68*4882a593Smuzhiyun 	}
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /* This function is the RTC interrupt service routine. */
mxc_rtc_interrupt(int irq,void * dev_id)72*4882a593Smuzhiyun static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	struct device *dev = dev_id;
75*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
76*4882a593Smuzhiyun 	void __iomem *ioaddr = pdata->ioaddr;
77*4882a593Smuzhiyun 	unsigned long flags;
78*4882a593Smuzhiyun 	u32 lp_status;
79*4882a593Smuzhiyun 	u32 lp_cr;
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	spin_lock_irqsave(&pdata->lock, flags);
82*4882a593Smuzhiyun 	if (clk_enable(pdata->clk)) {
83*4882a593Smuzhiyun 		spin_unlock_irqrestore(&pdata->lock, flags);
84*4882a593Smuzhiyun 		return IRQ_NONE;
85*4882a593Smuzhiyun 	}
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	lp_status = readl(ioaddr + SRTC_LPSR);
88*4882a593Smuzhiyun 	lp_cr = readl(ioaddr + SRTC_LPCR);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/* update irq data & counter */
91*4882a593Smuzhiyun 	if (lp_status & SRTC_LPSR_ALP) {
92*4882a593Smuzhiyun 		if (lp_cr & SRTC_LPCR_ALP)
93*4882a593Smuzhiyun 			rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 		/* disable further lp alarm interrupts */
96*4882a593Smuzhiyun 		lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
97*4882a593Smuzhiyun 	}
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun 	/* Update interrupt enables */
100*4882a593Smuzhiyun 	writel(lp_cr, ioaddr + SRTC_LPCR);
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	/* clear interrupt status */
103*4882a593Smuzhiyun 	writel(lp_status, ioaddr + SRTC_LPSR);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	mxc_rtc_sync_lp_locked(dev, ioaddr);
106*4882a593Smuzhiyun 	clk_disable(pdata->clk);
107*4882a593Smuzhiyun 	spin_unlock_irqrestore(&pdata->lock, flags);
108*4882a593Smuzhiyun 	return IRQ_HANDLED;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun /*
112*4882a593Smuzhiyun  * Enable clk and aquire spinlock
113*4882a593Smuzhiyun  * @return  0 if successful; non-zero otherwise.
114*4882a593Smuzhiyun  */
mxc_rtc_lock(struct mxc_rtc_data * const pdata)115*4882a593Smuzhiyun static int mxc_rtc_lock(struct mxc_rtc_data *const pdata)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun 	int ret;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	spin_lock_irq(&pdata->lock);
120*4882a593Smuzhiyun 	ret = clk_enable(pdata->clk);
121*4882a593Smuzhiyun 	if (ret) {
122*4882a593Smuzhiyun 		spin_unlock_irq(&pdata->lock);
123*4882a593Smuzhiyun 		return ret;
124*4882a593Smuzhiyun 	}
125*4882a593Smuzhiyun 	return 0;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
mxc_rtc_unlock(struct mxc_rtc_data * const pdata)128*4882a593Smuzhiyun static int mxc_rtc_unlock(struct mxc_rtc_data *const pdata)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	clk_disable(pdata->clk);
131*4882a593Smuzhiyun 	spin_unlock_irq(&pdata->lock);
132*4882a593Smuzhiyun 	return 0;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun  * This function reads the current RTC time into tm in Gregorian date.
137*4882a593Smuzhiyun  *
138*4882a593Smuzhiyun  * @param  tm           contains the RTC time value upon return
139*4882a593Smuzhiyun  *
140*4882a593Smuzhiyun  * @return  0 if successful; non-zero otherwise.
141*4882a593Smuzhiyun  */
mxc_rtc_read_time(struct device * dev,struct rtc_time * tm)142*4882a593Smuzhiyun static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
145*4882a593Smuzhiyun 	const int clk_failed = clk_enable(pdata->clk);
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 	if (!clk_failed) {
148*4882a593Smuzhiyun 		const time64_t now = readl(pdata->ioaddr + SRTC_LPSCMR);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 		rtc_time64_to_tm(now, tm);
151*4882a593Smuzhiyun 		clk_disable(pdata->clk);
152*4882a593Smuzhiyun 		return 0;
153*4882a593Smuzhiyun 	}
154*4882a593Smuzhiyun 	return clk_failed;
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun /*
158*4882a593Smuzhiyun  * This function sets the internal RTC time based on tm in Gregorian date.
159*4882a593Smuzhiyun  *
160*4882a593Smuzhiyun  * @param  tm           the time value to be set in the RTC
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * @return  0 if successful; non-zero otherwise.
163*4882a593Smuzhiyun  */
mxc_rtc_set_time(struct device * dev,struct rtc_time * tm)164*4882a593Smuzhiyun static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
167*4882a593Smuzhiyun 	time64_t time = rtc_tm_to_time64(tm);
168*4882a593Smuzhiyun 	int ret;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	ret = mxc_rtc_lock(pdata);
171*4882a593Smuzhiyun 	if (ret)
172*4882a593Smuzhiyun 		return ret;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 	writel(time, pdata->ioaddr + SRTC_LPSCMR);
175*4882a593Smuzhiyun 	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
176*4882a593Smuzhiyun 	return mxc_rtc_unlock(pdata);
177*4882a593Smuzhiyun }
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun /*
180*4882a593Smuzhiyun  * This function reads the current alarm value into the passed in \b alrm
181*4882a593Smuzhiyun  * argument. It updates the \b alrm's pending field value based on the whether
182*4882a593Smuzhiyun  * an alarm interrupt occurs or not.
183*4882a593Smuzhiyun  *
184*4882a593Smuzhiyun  * @param  alrm         contains the RTC alarm value upon return
185*4882a593Smuzhiyun  *
186*4882a593Smuzhiyun  * @return  0 if successful; non-zero otherwise.
187*4882a593Smuzhiyun  */
mxc_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alrm)188*4882a593Smuzhiyun static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
189*4882a593Smuzhiyun {
190*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
191*4882a593Smuzhiyun 	void __iomem *ioaddr = pdata->ioaddr;
192*4882a593Smuzhiyun 	int ret;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	ret = mxc_rtc_lock(pdata);
195*4882a593Smuzhiyun 	if (ret)
196*4882a593Smuzhiyun 		return ret;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	rtc_time64_to_tm(readl(ioaddr + SRTC_LPSAR), &alrm->time);
199*4882a593Smuzhiyun 	alrm->pending = !!(readl(ioaddr + SRTC_LPSR) & SRTC_LPSR_ALP);
200*4882a593Smuzhiyun 	return mxc_rtc_unlock(pdata);
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /*
204*4882a593Smuzhiyun  * Enable/Disable alarm interrupt
205*4882a593Smuzhiyun  * The caller should hold the pdata->lock
206*4882a593Smuzhiyun  */
mxc_rtc_alarm_irq_enable_locked(struct mxc_rtc_data * pdata,unsigned int enable)207*4882a593Smuzhiyun static void mxc_rtc_alarm_irq_enable_locked(struct mxc_rtc_data *pdata,
208*4882a593Smuzhiyun 					    unsigned int enable)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	u32 lp_cr = readl(pdata->ioaddr + SRTC_LPCR);
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	if (enable)
213*4882a593Smuzhiyun 		lp_cr |= (SRTC_LPCR_ALP | SRTC_LPCR_WAE);
214*4882a593Smuzhiyun 	else
215*4882a593Smuzhiyun 		lp_cr &= ~(SRTC_LPCR_ALP | SRTC_LPCR_WAE);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun 	writel(lp_cr, pdata->ioaddr + SRTC_LPCR);
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun 
mxc_rtc_alarm_irq_enable(struct device * dev,unsigned int enable)220*4882a593Smuzhiyun static int mxc_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
223*4882a593Smuzhiyun 	int ret = mxc_rtc_lock(pdata);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	if (ret)
226*4882a593Smuzhiyun 		return ret;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	mxc_rtc_alarm_irq_enable_locked(pdata, enable);
229*4882a593Smuzhiyun 	return mxc_rtc_unlock(pdata);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun /*
233*4882a593Smuzhiyun  * This function sets the RTC alarm based on passed in alrm.
234*4882a593Smuzhiyun  *
235*4882a593Smuzhiyun  * @param  alrm         the alarm value to be set in the RTC
236*4882a593Smuzhiyun  *
237*4882a593Smuzhiyun  * @return  0 if successful; non-zero otherwise.
238*4882a593Smuzhiyun  */
mxc_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alrm)239*4882a593Smuzhiyun static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	const time64_t time = rtc_tm_to_time64(&alrm->time);
242*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = dev_get_drvdata(dev);
243*4882a593Smuzhiyun 	int ret = mxc_rtc_lock(pdata);
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (ret)
246*4882a593Smuzhiyun 		return ret;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	writel((u32)time, pdata->ioaddr + SRTC_LPSAR);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	/* clear alarm interrupt status bit */
251*4882a593Smuzhiyun 	writel(SRTC_LPSR_ALP, pdata->ioaddr + SRTC_LPSR);
252*4882a593Smuzhiyun 	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	mxc_rtc_alarm_irq_enable_locked(pdata, alrm->enabled);
255*4882a593Smuzhiyun 	mxc_rtc_sync_lp_locked(dev, pdata->ioaddr);
256*4882a593Smuzhiyun 	mxc_rtc_unlock(pdata);
257*4882a593Smuzhiyun 	return ret;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun static const struct rtc_class_ops mxc_rtc_ops = {
261*4882a593Smuzhiyun 	.read_time = mxc_rtc_read_time,
262*4882a593Smuzhiyun 	.set_time = mxc_rtc_set_time,
263*4882a593Smuzhiyun 	.read_alarm = mxc_rtc_read_alarm,
264*4882a593Smuzhiyun 	.set_alarm = mxc_rtc_set_alarm,
265*4882a593Smuzhiyun 	.alarm_irq_enable = mxc_rtc_alarm_irq_enable,
266*4882a593Smuzhiyun };
267*4882a593Smuzhiyun 
mxc_rtc_wait_for_flag(void __iomem * ioaddr,int flag)268*4882a593Smuzhiyun static int mxc_rtc_wait_for_flag(void __iomem *ioaddr, int flag)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	unsigned int timeout = REG_READ_TIMEOUT;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	while (!(readl(ioaddr) & flag)) {
273*4882a593Smuzhiyun 		if (!--timeout)
274*4882a593Smuzhiyun 			return -EBUSY;
275*4882a593Smuzhiyun 	}
276*4882a593Smuzhiyun 	return 0;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun 
mxc_rtc_probe(struct platform_device * pdev)279*4882a593Smuzhiyun static int mxc_rtc_probe(struct platform_device *pdev)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata;
282*4882a593Smuzhiyun 	void __iomem *ioaddr;
283*4882a593Smuzhiyun 	int ret = 0;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
286*4882a593Smuzhiyun 	if (!pdata)
287*4882a593Smuzhiyun 		return -ENOMEM;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	pdata->ioaddr = devm_platform_ioremap_resource(pdev, 0);
290*4882a593Smuzhiyun 	if (IS_ERR(pdata->ioaddr))
291*4882a593Smuzhiyun 		return PTR_ERR(pdata->ioaddr);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	ioaddr = pdata->ioaddr;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	pdata->clk = devm_clk_get(&pdev->dev, NULL);
296*4882a593Smuzhiyun 	if (IS_ERR(pdata->clk)) {
297*4882a593Smuzhiyun 		dev_err(&pdev->dev, "unable to get rtc clock!\n");
298*4882a593Smuzhiyun 		return PTR_ERR(pdata->clk);
299*4882a593Smuzhiyun 	}
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	spin_lock_init(&pdata->lock);
302*4882a593Smuzhiyun 	pdata->irq = platform_get_irq(pdev, 0);
303*4882a593Smuzhiyun 	if (pdata->irq < 0)
304*4882a593Smuzhiyun 		return pdata->irq;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	device_init_wakeup(&pdev->dev, 1);
307*4882a593Smuzhiyun 	ret = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
308*4882a593Smuzhiyun 	if (ret)
309*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to enable irq wake\n");
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	ret = clk_prepare_enable(pdata->clk);
312*4882a593Smuzhiyun 	if (ret)
313*4882a593Smuzhiyun 		return ret;
314*4882a593Smuzhiyun 	/* initialize glitch detect */
315*4882a593Smuzhiyun 	writel(SRTC_LPPDR_INIT, ioaddr + SRTC_LPPDR);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	/* clear lp interrupt status */
318*4882a593Smuzhiyun 	writel(0xFFFFFFFF, ioaddr + SRTC_LPSR);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	/* move out of init state */
321*4882a593Smuzhiyun 	writel((SRTC_LPCR_IE | SRTC_LPCR_NSA), ioaddr + SRTC_LPCR);
322*4882a593Smuzhiyun 	ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_IES);
323*4882a593Smuzhiyun 	if (ret) {
324*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_IES\n");
325*4882a593Smuzhiyun 		clk_disable_unprepare(pdata->clk);
326*4882a593Smuzhiyun 		return ret;
327*4882a593Smuzhiyun 	}
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	/* move out of non-valid state */
330*4882a593Smuzhiyun 	writel((SRTC_LPCR_IE | SRTC_LPCR_NVE | SRTC_LPCR_NSA |
331*4882a593Smuzhiyun 		SRTC_LPCR_EN_LP), ioaddr + SRTC_LPCR);
332*4882a593Smuzhiyun 	ret = mxc_rtc_wait_for_flag(ioaddr + SRTC_LPSR, SRTC_LPSR_NVES);
333*4882a593Smuzhiyun 	if (ret) {
334*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Timeout waiting for SRTC_LPSR_NVES\n");
335*4882a593Smuzhiyun 		clk_disable_unprepare(pdata->clk);
336*4882a593Smuzhiyun 		return ret;
337*4882a593Smuzhiyun 	}
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	pdata->rtc = devm_rtc_allocate_device(&pdev->dev);
340*4882a593Smuzhiyun 	if (IS_ERR(pdata->rtc))
341*4882a593Smuzhiyun 		return PTR_ERR(pdata->rtc);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	pdata->rtc->ops = &mxc_rtc_ops;
344*4882a593Smuzhiyun 	pdata->rtc->range_max = U32_MAX;
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun 	clk_disable(pdata->clk);
347*4882a593Smuzhiyun 	platform_set_drvdata(pdev, pdata);
348*4882a593Smuzhiyun 	ret =
349*4882a593Smuzhiyun 	    devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, 0,
350*4882a593Smuzhiyun 			     pdev->name, &pdev->dev);
351*4882a593Smuzhiyun 	if (ret < 0) {
352*4882a593Smuzhiyun 		dev_err(&pdev->dev, "interrupt not available.\n");
353*4882a593Smuzhiyun 		clk_unprepare(pdata->clk);
354*4882a593Smuzhiyun 		return ret;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	ret = rtc_register_device(pdata->rtc);
358*4882a593Smuzhiyun 	if (ret < 0)
359*4882a593Smuzhiyun 		clk_unprepare(pdata->clk);
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	return ret;
362*4882a593Smuzhiyun }
363*4882a593Smuzhiyun 
mxc_rtc_remove(struct platform_device * pdev)364*4882a593Smuzhiyun static int mxc_rtc_remove(struct platform_device *pdev)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	struct mxc_rtc_data *pdata = platform_get_drvdata(pdev);
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	clk_disable_unprepare(pdata->clk);
369*4882a593Smuzhiyun 	return 0;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun static const struct of_device_id mxc_ids[] = {
373*4882a593Smuzhiyun 	{ .compatible = "fsl,imx53-rtc", },
374*4882a593Smuzhiyun 	{}
375*4882a593Smuzhiyun };
376*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, mxc_ids);
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun static struct platform_driver mxc_rtc_driver = {
379*4882a593Smuzhiyun 	.driver = {
380*4882a593Smuzhiyun 		.name = "mxc_rtc_v2",
381*4882a593Smuzhiyun 		.of_match_table = mxc_ids,
382*4882a593Smuzhiyun 	},
383*4882a593Smuzhiyun 	.probe = mxc_rtc_probe,
384*4882a593Smuzhiyun 	.remove = mxc_rtc_remove,
385*4882a593Smuzhiyun };
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun module_platform_driver(mxc_rtc_driver);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun MODULE_AUTHOR("Freescale Semiconductor, Inc.");
390*4882a593Smuzhiyun MODULE_DESCRIPTION("Real Time Clock (RTC) Driver for i.MX53");
391*4882a593Smuzhiyun MODULE_LICENSE("GPL");
392