xref: /OK3568_Linux_fs/kernel/drivers/rtc/rtc-sirfsoc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * SiRFSoC Real Time Clock interface for Linux
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2013 Cambridge Silicon Radio Limited, a CSR plc group company.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/module.h>
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/rtc.h>
11*4882a593Smuzhiyun #include <linux/platform_device.h>
12*4882a593Smuzhiyun #include <linux/slab.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/of.h>
15*4882a593Smuzhiyun #include <linux/regmap.h>
16*4882a593Smuzhiyun #include <linux/rtc/sirfsoc_rtciobrg.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define RTC_CN			0x00
20*4882a593Smuzhiyun #define RTC_ALARM0		0x04
21*4882a593Smuzhiyun #define RTC_ALARM1		0x18
22*4882a593Smuzhiyun #define RTC_STATUS		0x08
23*4882a593Smuzhiyun #define RTC_SW_VALUE            0x40
24*4882a593Smuzhiyun #define SIRFSOC_RTC_AL1E	(1<<6)
25*4882a593Smuzhiyun #define SIRFSOC_RTC_AL1		(1<<4)
26*4882a593Smuzhiyun #define SIRFSOC_RTC_HZE		(1<<3)
27*4882a593Smuzhiyun #define SIRFSOC_RTC_AL0E	(1<<2)
28*4882a593Smuzhiyun #define SIRFSOC_RTC_HZ		(1<<1)
29*4882a593Smuzhiyun #define SIRFSOC_RTC_AL0		(1<<0)
30*4882a593Smuzhiyun #define RTC_DIV			0x0c
31*4882a593Smuzhiyun #define RTC_DEEP_CTRL		0x14
32*4882a593Smuzhiyun #define RTC_CLOCK_SWITCH	0x1c
33*4882a593Smuzhiyun #define SIRFSOC_RTC_CLK		0x03	/* others are reserved */
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun /* Refer to RTC DIV switch */
36*4882a593Smuzhiyun #define RTC_HZ			16
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /* This macro is also defined in arch/arm/plat-sirfsoc/cpu.c */
39*4882a593Smuzhiyun #define RTC_SHIFT		4
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define INTR_SYSRTC_CN		0x48
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun struct sirfsoc_rtc_drv {
44*4882a593Smuzhiyun 	struct rtc_device	*rtc;
45*4882a593Smuzhiyun 	u32			rtc_base;
46*4882a593Smuzhiyun 	u32			irq;
47*4882a593Smuzhiyun 	unsigned		irq_wake;
48*4882a593Smuzhiyun 	/* Overflow for every 8 years extra time */
49*4882a593Smuzhiyun 	u32			overflow_rtc;
50*4882a593Smuzhiyun 	spinlock_t		lock;
51*4882a593Smuzhiyun 	struct regmap *regmap;
52*4882a593Smuzhiyun #ifdef CONFIG_PM
53*4882a593Smuzhiyun 	u32		saved_counter;
54*4882a593Smuzhiyun 	u32		saved_overflow_rtc;
55*4882a593Smuzhiyun #endif
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun 
sirfsoc_rtc_readl(struct sirfsoc_rtc_drv * rtcdrv,u32 offset)58*4882a593Smuzhiyun static u32 sirfsoc_rtc_readl(struct sirfsoc_rtc_drv *rtcdrv, u32 offset)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	u32 val;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	regmap_read(rtcdrv->regmap, rtcdrv->rtc_base + offset, &val);
63*4882a593Smuzhiyun 	return val;
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
sirfsoc_rtc_writel(struct sirfsoc_rtc_drv * rtcdrv,u32 offset,u32 val)66*4882a593Smuzhiyun static void sirfsoc_rtc_writel(struct sirfsoc_rtc_drv *rtcdrv,
67*4882a593Smuzhiyun 			       u32 offset, u32 val)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun 	regmap_write(rtcdrv->regmap, rtcdrv->rtc_base + offset, val);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
sirfsoc_rtc_read_alarm(struct device * dev,struct rtc_wkalrm * alrm)72*4882a593Smuzhiyun static int sirfsoc_rtc_read_alarm(struct device *dev,
73*4882a593Smuzhiyun 		struct rtc_wkalrm *alrm)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun 	unsigned long rtc_alarm, rtc_count;
76*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	rtcdrv = dev_get_drvdata(dev);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun 	spin_lock_irq(&rtcdrv->lock);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	rtc_count = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
83*4882a593Smuzhiyun 
84*4882a593Smuzhiyun 	rtc_alarm = sirfsoc_rtc_readl(rtcdrv, RTC_ALARM0);
85*4882a593Smuzhiyun 	memset(alrm, 0, sizeof(struct rtc_wkalrm));
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	/*
88*4882a593Smuzhiyun 	 * assume alarm interval not beyond one round counter overflow_rtc:
89*4882a593Smuzhiyun 	 * 0->0xffffffff
90*4882a593Smuzhiyun 	 */
91*4882a593Smuzhiyun 	/* if alarm is in next overflow cycle */
92*4882a593Smuzhiyun 	if (rtc_count > rtc_alarm)
93*4882a593Smuzhiyun 		rtc_time64_to_tm((rtcdrv->overflow_rtc + 1)
94*4882a593Smuzhiyun 				 << (BITS_PER_LONG - RTC_SHIFT)
95*4882a593Smuzhiyun 				 | rtc_alarm >> RTC_SHIFT, &alrm->time);
96*4882a593Smuzhiyun 	else
97*4882a593Smuzhiyun 		rtc_time64_to_tm(rtcdrv->overflow_rtc
98*4882a593Smuzhiyun 				 << (BITS_PER_LONG - RTC_SHIFT)
99*4882a593Smuzhiyun 				 | rtc_alarm >> RTC_SHIFT, &alrm->time);
100*4882a593Smuzhiyun 	if (sirfsoc_rtc_readl(rtcdrv, RTC_STATUS) & SIRFSOC_RTC_AL0E)
101*4882a593Smuzhiyun 		alrm->enabled = 1;
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	spin_unlock_irq(&rtcdrv->lock);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	return 0;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun 
sirfsoc_rtc_set_alarm(struct device * dev,struct rtc_wkalrm * alrm)108*4882a593Smuzhiyun static int sirfsoc_rtc_set_alarm(struct device *dev,
109*4882a593Smuzhiyun 		struct rtc_wkalrm *alrm)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	unsigned long rtc_status_reg, rtc_alarm;
112*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
113*4882a593Smuzhiyun 	rtcdrv = dev_get_drvdata(dev);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	if (alrm->enabled) {
116*4882a593Smuzhiyun 		rtc_alarm = rtc_tm_to_time64(&alrm->time);
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 		spin_lock_irq(&rtcdrv->lock);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 		rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
121*4882a593Smuzhiyun 		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
122*4882a593Smuzhiyun 			/*
123*4882a593Smuzhiyun 			 * An ongoing alarm in progress - ingore it and not
124*4882a593Smuzhiyun 			 * to return EBUSY
125*4882a593Smuzhiyun 			 */
126*4882a593Smuzhiyun 			dev_info(dev, "An old alarm was set, will be replaced by a new one\n");
127*4882a593Smuzhiyun 		}
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, rtc_alarm << RTC_SHIFT);
130*4882a593Smuzhiyun 		rtc_status_reg &= ~0x07; /* mask out the lower status bits */
131*4882a593Smuzhiyun 		/*
132*4882a593Smuzhiyun 		 * This bit RTC_AL sets it as a wake-up source for Sleep Mode
133*4882a593Smuzhiyun 		 * Writing 1 into this bit will clear it
134*4882a593Smuzhiyun 		 */
135*4882a593Smuzhiyun 		rtc_status_reg |= SIRFSOC_RTC_AL0;
136*4882a593Smuzhiyun 		/* enable the RTC alarm interrupt */
137*4882a593Smuzhiyun 		rtc_status_reg |= SIRFSOC_RTC_AL0E;
138*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 		spin_unlock_irq(&rtcdrv->lock);
141*4882a593Smuzhiyun 	} else {
142*4882a593Smuzhiyun 		/*
143*4882a593Smuzhiyun 		 * if this function was called with enabled=0
144*4882a593Smuzhiyun 		 * then it could mean that the application is
145*4882a593Smuzhiyun 		 * trying to cancel an ongoing alarm
146*4882a593Smuzhiyun 		 */
147*4882a593Smuzhiyun 		spin_lock_irq(&rtcdrv->lock);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 		rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
150*4882a593Smuzhiyun 		if (rtc_status_reg & SIRFSOC_RTC_AL0E) {
151*4882a593Smuzhiyun 			/* clear the RTC status register's alarm bit */
152*4882a593Smuzhiyun 			rtc_status_reg &= ~0x07;
153*4882a593Smuzhiyun 			/* write 1 into SIRFSOC_RTC_AL0 to force a clear */
154*4882a593Smuzhiyun 			rtc_status_reg |= (SIRFSOC_RTC_AL0);
155*4882a593Smuzhiyun 			/* Clear the Alarm enable bit */
156*4882a593Smuzhiyun 			rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 			sirfsoc_rtc_writel(rtcdrv, RTC_STATUS,
159*4882a593Smuzhiyun 					   rtc_status_reg);
160*4882a593Smuzhiyun 		}
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 		spin_unlock_irq(&rtcdrv->lock);
163*4882a593Smuzhiyun 	}
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	return 0;
166*4882a593Smuzhiyun }
167*4882a593Smuzhiyun 
sirfsoc_rtc_read_time(struct device * dev,struct rtc_time * tm)168*4882a593Smuzhiyun static int sirfsoc_rtc_read_time(struct device *dev,
169*4882a593Smuzhiyun 		struct rtc_time *tm)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	unsigned long tmp_rtc = 0;
172*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
173*4882a593Smuzhiyun 	rtcdrv = dev_get_drvdata(dev);
174*4882a593Smuzhiyun 	/*
175*4882a593Smuzhiyun 	 * This patch is taken from WinCE - Need to validate this for
176*4882a593Smuzhiyun 	 * correctness. To work around sirfsoc RTC counter double sync logic
177*4882a593Smuzhiyun 	 * fail, read several times to make sure get stable value.
178*4882a593Smuzhiyun 	 */
179*4882a593Smuzhiyun 	do {
180*4882a593Smuzhiyun 		tmp_rtc = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
181*4882a593Smuzhiyun 		cpu_relax();
182*4882a593Smuzhiyun 	} while (tmp_rtc != sirfsoc_rtc_readl(rtcdrv, RTC_CN));
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	rtc_time64_to_tm(rtcdrv->overflow_rtc << (BITS_PER_LONG - RTC_SHIFT)
185*4882a593Smuzhiyun 			 | tmp_rtc >> RTC_SHIFT, tm);
186*4882a593Smuzhiyun 	return 0;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
sirfsoc_rtc_set_time(struct device * dev,struct rtc_time * tm)189*4882a593Smuzhiyun static int sirfsoc_rtc_set_time(struct device *dev,
190*4882a593Smuzhiyun 		struct rtc_time *tm)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	unsigned long rtc_time;
193*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
194*4882a593Smuzhiyun 	rtcdrv = dev_get_drvdata(dev);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	rtc_time = rtc_tm_to_time64(tm);
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	rtcdrv->overflow_rtc = rtc_time >> (BITS_PER_LONG - RTC_SHIFT);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
201*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_CN, rtc_time << RTC_SHIFT);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	return 0;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
sirfsoc_rtc_alarm_irq_enable(struct device * dev,unsigned int enabled)206*4882a593Smuzhiyun static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
207*4882a593Smuzhiyun 		unsigned int enabled)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	unsigned long rtc_status_reg = 0x0;
210*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	rtcdrv = dev_get_drvdata(dev);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	spin_lock_irq(&rtcdrv->lock);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
217*4882a593Smuzhiyun 	if (enabled)
218*4882a593Smuzhiyun 		rtc_status_reg |= SIRFSOC_RTC_AL0E;
219*4882a593Smuzhiyun 	else
220*4882a593Smuzhiyun 		rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	spin_unlock_irq(&rtcdrv->lock);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	return 0;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun static const struct rtc_class_ops sirfsoc_rtc_ops = {
231*4882a593Smuzhiyun 	.read_time = sirfsoc_rtc_read_time,
232*4882a593Smuzhiyun 	.set_time = sirfsoc_rtc_set_time,
233*4882a593Smuzhiyun 	.read_alarm = sirfsoc_rtc_read_alarm,
234*4882a593Smuzhiyun 	.set_alarm = sirfsoc_rtc_set_alarm,
235*4882a593Smuzhiyun 	.alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
sirfsoc_rtc_irq_handler(int irq,void * pdata)238*4882a593Smuzhiyun static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv = pdata;
241*4882a593Smuzhiyun 	unsigned long rtc_status_reg = 0x0;
242*4882a593Smuzhiyun 	unsigned long events = 0x0;
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun 	spin_lock(&rtcdrv->lock);
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun 	rtc_status_reg = sirfsoc_rtc_readl(rtcdrv, RTC_STATUS);
247*4882a593Smuzhiyun 	/* this bit will be set ONLY if an alarm was active
248*4882a593Smuzhiyun 	 * and it expired NOW
249*4882a593Smuzhiyun 	 * So this is being used as an ASSERT
250*4882a593Smuzhiyun 	 */
251*4882a593Smuzhiyun 	if (rtc_status_reg & SIRFSOC_RTC_AL0) {
252*4882a593Smuzhiyun 		/*
253*4882a593Smuzhiyun 		 * clear the RTC status register's alarm bit
254*4882a593Smuzhiyun 		 * mask out the lower status bits
255*4882a593Smuzhiyun 		 */
256*4882a593Smuzhiyun 		rtc_status_reg &= ~0x07;
257*4882a593Smuzhiyun 		/* write 1 into SIRFSOC_RTC_AL0 to ACK the alarm interrupt */
258*4882a593Smuzhiyun 		rtc_status_reg |= (SIRFSOC_RTC_AL0);
259*4882a593Smuzhiyun 		/* Clear the Alarm enable bit */
260*4882a593Smuzhiyun 		rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_STATUS, rtc_status_reg);
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	spin_unlock(&rtcdrv->lock);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun 	/* this should wake up any apps polling/waiting on the read
268*4882a593Smuzhiyun 	 * after setting the alarm
269*4882a593Smuzhiyun 	 */
270*4882a593Smuzhiyun 	events |= RTC_IRQF | RTC_AF;
271*4882a593Smuzhiyun 	rtc_update_irq(rtcdrv->rtc, 1, events);
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	return IRQ_HANDLED;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun static const struct of_device_id sirfsoc_rtc_of_match[] = {
277*4882a593Smuzhiyun 	{ .compatible = "sirf,prima2-sysrtc"},
278*4882a593Smuzhiyun 	{},
279*4882a593Smuzhiyun };
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun static const struct regmap_config sysrtc_regmap_config = {
282*4882a593Smuzhiyun 	.reg_bits = 32,
283*4882a593Smuzhiyun 	.val_bits = 32,
284*4882a593Smuzhiyun 	.fast_io = true,
285*4882a593Smuzhiyun };
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, sirfsoc_rtc_of_match);
288*4882a593Smuzhiyun 
sirfsoc_rtc_probe(struct platform_device * pdev)289*4882a593Smuzhiyun static int sirfsoc_rtc_probe(struct platform_device *pdev)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun 	int err;
292*4882a593Smuzhiyun 	unsigned long rtc_div;
293*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv;
294*4882a593Smuzhiyun 	struct device_node *np = pdev->dev.of_node;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	rtcdrv = devm_kzalloc(&pdev->dev,
297*4882a593Smuzhiyun 		sizeof(struct sirfsoc_rtc_drv), GFP_KERNEL);
298*4882a593Smuzhiyun 	if (rtcdrv == NULL)
299*4882a593Smuzhiyun 		return -ENOMEM;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 	spin_lock_init(&rtcdrv->lock);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 	err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
304*4882a593Smuzhiyun 	if (err) {
305*4882a593Smuzhiyun 		dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
306*4882a593Smuzhiyun 		return err;
307*4882a593Smuzhiyun 	}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	platform_set_drvdata(pdev, rtcdrv);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	/* Register rtc alarm as a wakeup source */
312*4882a593Smuzhiyun 	device_init_wakeup(&pdev->dev, 1);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	rtcdrv->regmap = devm_regmap_init_iobg(&pdev->dev,
315*4882a593Smuzhiyun 			&sysrtc_regmap_config);
316*4882a593Smuzhiyun 	if (IS_ERR(rtcdrv->regmap)) {
317*4882a593Smuzhiyun 		err = PTR_ERR(rtcdrv->regmap);
318*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Failed to allocate register map: %d\n",
319*4882a593Smuzhiyun 			err);
320*4882a593Smuzhiyun 		return err;
321*4882a593Smuzhiyun 	}
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	/*
324*4882a593Smuzhiyun 	 * Set SYS_RTC counter in RTC_HZ HZ Units
325*4882a593Smuzhiyun 	 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
326*4882a593Smuzhiyun 	 * If 16HZ, therefore RTC_DIV = 1023;
327*4882a593Smuzhiyun 	 */
328*4882a593Smuzhiyun 	rtc_div = ((32768 / RTC_HZ) / 2) - 1;
329*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	/* 0x3 -> RTC_CLK */
332*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	/* reset SYS RTC ALARM0 */
335*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	/* reset SYS RTC ALARM1 */
338*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	/* Restore RTC Overflow From Register After Command Reboot */
341*4882a593Smuzhiyun 	rtcdrv->overflow_rtc =
342*4882a593Smuzhiyun 		sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	rtcdrv->rtc = devm_rtc_allocate_device(&pdev->dev);
345*4882a593Smuzhiyun 	if (IS_ERR(rtcdrv->rtc))
346*4882a593Smuzhiyun 		return PTR_ERR(rtcdrv->rtc);
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	rtcdrv->rtc->ops = &sirfsoc_rtc_ops;
349*4882a593Smuzhiyun 	rtcdrv->rtc->range_max = (1ULL << 60) - 1;
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	rtcdrv->irq = platform_get_irq(pdev, 0);
352*4882a593Smuzhiyun 	err = devm_request_irq(&pdev->dev, rtcdrv->irq, sirfsoc_rtc_irq_handler,
353*4882a593Smuzhiyun 			       IRQF_SHARED, pdev->name, rtcdrv);
354*4882a593Smuzhiyun 	if (err) {
355*4882a593Smuzhiyun 		dev_err(&pdev->dev, "Unable to register for the SiRF SOC RTC IRQ\n");
356*4882a593Smuzhiyun 		return err;
357*4882a593Smuzhiyun 	}
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	return rtc_register_device(rtcdrv->rtc);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
sirfsoc_rtc_suspend(struct device * dev)363*4882a593Smuzhiyun static int sirfsoc_rtc_suspend(struct device *dev)
364*4882a593Smuzhiyun {
365*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
366*4882a593Smuzhiyun 	rtcdrv->overflow_rtc =
367*4882a593Smuzhiyun 		sirfsoc_rtc_readl(rtcdrv, RTC_SW_VALUE);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	rtcdrv->saved_counter =
370*4882a593Smuzhiyun 		sirfsoc_rtc_readl(rtcdrv, RTC_CN);
371*4882a593Smuzhiyun 	rtcdrv->saved_overflow_rtc = rtcdrv->overflow_rtc;
372*4882a593Smuzhiyun 	if (device_may_wakeup(dev) && !enable_irq_wake(rtcdrv->irq))
373*4882a593Smuzhiyun 		rtcdrv->irq_wake = 1;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun 
sirfsoc_rtc_resume(struct device * dev)378*4882a593Smuzhiyun static int sirfsoc_rtc_resume(struct device *dev)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun 	u32 tmp;
381*4882a593Smuzhiyun 	struct sirfsoc_rtc_drv *rtcdrv = dev_get_drvdata(dev);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	/*
384*4882a593Smuzhiyun 	 * if resume from snapshot and the rtc power is lost,
385*4882a593Smuzhiyun 	 * restroe the rtc settings
386*4882a593Smuzhiyun 	 */
387*4882a593Smuzhiyun 	if (SIRFSOC_RTC_CLK != sirfsoc_rtc_readl(rtcdrv, RTC_CLOCK_SWITCH)) {
388*4882a593Smuzhiyun 		u32 rtc_div;
389*4882a593Smuzhiyun 		/* 0x3 -> RTC_CLK */
390*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_CLOCK_SWITCH, SIRFSOC_RTC_CLK);
391*4882a593Smuzhiyun 		/*
392*4882a593Smuzhiyun 		 * Set SYS_RTC counter in RTC_HZ HZ Units
393*4882a593Smuzhiyun 		 * We are using 32K RTC crystal (32768 / RTC_HZ / 2) -1
394*4882a593Smuzhiyun 		 * If 16HZ, therefore RTC_DIV = 1023;
395*4882a593Smuzhiyun 		 */
396*4882a593Smuzhiyun 		rtc_div = ((32768 / RTC_HZ) / 2) - 1;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_DIV, rtc_div);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 		/* reset SYS RTC ALARM0 */
401*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM0, 0x0);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 		/* reset SYS RTC ALARM1 */
404*4882a593Smuzhiyun 		sirfsoc_rtc_writel(rtcdrv, RTC_ALARM1, 0x0);
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 	rtcdrv->overflow_rtc = rtcdrv->saved_overflow_rtc;
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	/*
409*4882a593Smuzhiyun 	 * if current counter is small than previous,
410*4882a593Smuzhiyun 	 * it means overflow in sleep
411*4882a593Smuzhiyun 	 */
412*4882a593Smuzhiyun 	tmp = sirfsoc_rtc_readl(rtcdrv, RTC_CN);
413*4882a593Smuzhiyun 	if (tmp <= rtcdrv->saved_counter)
414*4882a593Smuzhiyun 		rtcdrv->overflow_rtc++;
415*4882a593Smuzhiyun 	/*
416*4882a593Smuzhiyun 	 *PWRC Value Be Changed When Suspend, Restore Overflow
417*4882a593Smuzhiyun 	 * In Memory To Register
418*4882a593Smuzhiyun 	 */
419*4882a593Smuzhiyun 	sirfsoc_rtc_writel(rtcdrv, RTC_SW_VALUE, rtcdrv->overflow_rtc);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (device_may_wakeup(dev) && rtcdrv->irq_wake) {
422*4882a593Smuzhiyun 		disable_irq_wake(rtcdrv->irq);
423*4882a593Smuzhiyun 		rtcdrv->irq_wake = 0;
424*4882a593Smuzhiyun 	}
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	return 0;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun #endif
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(sirfsoc_rtc_pm_ops,
431*4882a593Smuzhiyun 		sirfsoc_rtc_suspend, sirfsoc_rtc_resume);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun static struct platform_driver sirfsoc_rtc_driver = {
434*4882a593Smuzhiyun 	.driver = {
435*4882a593Smuzhiyun 		.name = "sirfsoc-rtc",
436*4882a593Smuzhiyun 		.pm = &sirfsoc_rtc_pm_ops,
437*4882a593Smuzhiyun 		.of_match_table = sirfsoc_rtc_of_match,
438*4882a593Smuzhiyun 	},
439*4882a593Smuzhiyun 	.probe = sirfsoc_rtc_probe,
440*4882a593Smuzhiyun };
441*4882a593Smuzhiyun module_platform_driver(sirfsoc_rtc_driver);
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun MODULE_DESCRIPTION("SiRF SoC rtc driver");
444*4882a593Smuzhiyun MODULE_AUTHOR("Xianglong Du <Xianglong.Du@csr.com>");
445*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
446*4882a593Smuzhiyun MODULE_ALIAS("platform:sirfsoc-rtc");
447