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