Version:  2.0.40 2.2.26 2.4.37 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16

Linux/drivers/rtc/rtc-sirfsoc.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us