aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-sirfsoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-sirfsoc.c')
-rw-r--r--drivers/rtc/rtc-sirfsoc.c66
1 files changed, 51 insertions, 15 deletions
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
index 76e38007ba90..d2ac6688e5c7 100644
--- a/drivers/rtc/rtc-sirfsoc.c
+++ b/drivers/rtc/rtc-sirfsoc.c
@@ -47,6 +47,7 @@ struct sirfsoc_rtc_drv {
47 unsigned irq_wake; 47 unsigned irq_wake;
48 /* Overflow for every 8 years extra time */ 48 /* Overflow for every 8 years extra time */
49 u32 overflow_rtc; 49 u32 overflow_rtc;
50 spinlock_t lock;
50#ifdef CONFIG_PM 51#ifdef CONFIG_PM
51 u32 saved_counter; 52 u32 saved_counter;
52 u32 saved_overflow_rtc; 53 u32 saved_overflow_rtc;
@@ -61,7 +62,7 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
61 62
62 rtcdrv = dev_get_drvdata(dev); 63 rtcdrv = dev_get_drvdata(dev);
63 64
64 local_irq_disable(); 65 spin_lock_irq(&rtcdrv->lock);
65 66
66 rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN); 67 rtc_count = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_CN);
67 68
@@ -84,7 +85,8 @@ static int sirfsoc_rtc_read_alarm(struct device *dev,
84 if (sirfsoc_rtc_iobrg_readl( 85 if (sirfsoc_rtc_iobrg_readl(
85 rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E) 86 rtcdrv->rtc_base + RTC_STATUS) & SIRFSOC_RTC_AL0E)
86 alrm->enabled = 1; 87 alrm->enabled = 1;
87 local_irq_enable(); 88
89 spin_unlock_irq(&rtcdrv->lock);
88 90
89 return 0; 91 return 0;
90} 92}
@@ -99,7 +101,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
99 if (alrm->enabled) { 101 if (alrm->enabled) {
100 rtc_tm_to_time(&(alrm->time), &rtc_alarm); 102 rtc_tm_to_time(&(alrm->time), &rtc_alarm);
101 103
102 local_irq_disable(); 104 spin_lock_irq(&rtcdrv->lock);
103 105
104 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 106 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
105 rtcdrv->rtc_base + RTC_STATUS); 107 rtcdrv->rtc_base + RTC_STATUS);
@@ -123,14 +125,15 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
123 rtc_status_reg |= SIRFSOC_RTC_AL0E; 125 rtc_status_reg |= SIRFSOC_RTC_AL0E;
124 sirfsoc_rtc_iobrg_writel( 126 sirfsoc_rtc_iobrg_writel(
125 rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 127 rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
126 local_irq_enable(); 128
129 spin_unlock_irq(&rtcdrv->lock);
127 } else { 130 } else {
128 /* 131 /*
129 * if this function was called with enabled=0 132 * if this function was called with enabled=0
130 * then it could mean that the application is 133 * then it could mean that the application is
131 * trying to cancel an ongoing alarm 134 * trying to cancel an ongoing alarm
132 */ 135 */
133 local_irq_disable(); 136 spin_lock_irq(&rtcdrv->lock);
134 137
135 rtc_status_reg = sirfsoc_rtc_iobrg_readl( 138 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
136 rtcdrv->rtc_base + RTC_STATUS); 139 rtcdrv->rtc_base + RTC_STATUS);
@@ -146,7 +149,7 @@ static int sirfsoc_rtc_set_alarm(struct device *dev,
146 rtcdrv->rtc_base + RTC_STATUS); 149 rtcdrv->rtc_base + RTC_STATUS);
147 } 150 }
148 151
149 local_irq_enable(); 152 spin_unlock_irq(&rtcdrv->lock);
150 } 153 }
151 154
152 return 0; 155 return 0;
@@ -209,12 +212,38 @@ static int sirfsoc_rtc_ioctl(struct device *dev, unsigned int cmd,
209 } 212 }
210} 213}
211 214
215static int sirfsoc_rtc_alarm_irq_enable(struct device *dev,
216 unsigned int enabled)
217{
218 unsigned long rtc_status_reg = 0x0;
219 struct sirfsoc_rtc_drv *rtcdrv;
220
221 rtcdrv = dev_get_drvdata(dev);
222
223 spin_lock_irq(&rtcdrv->lock);
224
225 rtc_status_reg = sirfsoc_rtc_iobrg_readl(
226 rtcdrv->rtc_base + RTC_STATUS);
227 if (enabled)
228 rtc_status_reg |= SIRFSOC_RTC_AL0E;
229 else
230 rtc_status_reg &= ~SIRFSOC_RTC_AL0E;
231
232 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
233
234 spin_unlock_irq(&rtcdrv->lock);
235
236 return 0;
237
238}
239
212static const struct rtc_class_ops sirfsoc_rtc_ops = { 240static const struct rtc_class_ops sirfsoc_rtc_ops = {
213 .read_time = sirfsoc_rtc_read_time, 241 .read_time = sirfsoc_rtc_read_time,
214 .set_time = sirfsoc_rtc_set_time, 242 .set_time = sirfsoc_rtc_set_time,
215 .read_alarm = sirfsoc_rtc_read_alarm, 243 .read_alarm = sirfsoc_rtc_read_alarm,
216 .set_alarm = sirfsoc_rtc_set_alarm, 244 .set_alarm = sirfsoc_rtc_set_alarm,
217 .ioctl = sirfsoc_rtc_ioctl 245 .ioctl = sirfsoc_rtc_ioctl,
246 .alarm_irq_enable = sirfsoc_rtc_alarm_irq_enable
218}; 247};
219 248
220static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata) 249static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
@@ -223,6 +252,8 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
223 unsigned long rtc_status_reg = 0x0; 252 unsigned long rtc_status_reg = 0x0;
224 unsigned long events = 0x0; 253 unsigned long events = 0x0;
225 254
255 spin_lock(&rtcdrv->lock);
256
226 rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS); 257 rtc_status_reg = sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_STATUS);
227 /* this bit will be set ONLY if an alarm was active 258 /* this bit will be set ONLY if an alarm was active
228 * and it expired NOW 259 * and it expired NOW
@@ -240,6 +271,9 @@ static irqreturn_t sirfsoc_rtc_irq_handler(int irq, void *pdata)
240 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E); 271 rtc_status_reg &= ~(SIRFSOC_RTC_AL0E);
241 } 272 }
242 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS); 273 sirfsoc_rtc_iobrg_writel(rtc_status_reg, rtcdrv->rtc_base + RTC_STATUS);
274
275 spin_unlock(&rtcdrv->lock);
276
243 /* this should wake up any apps polling/waiting on the read 277 /* this should wake up any apps polling/waiting on the read
244 * after setting the alarm 278 * after setting the alarm
245 */ 279 */
@@ -267,6 +301,8 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
267 if (rtcdrv == NULL) 301 if (rtcdrv == NULL)
268 return -ENOMEM; 302 return -ENOMEM;
269 303
304 spin_lock_init(&rtcdrv->lock);
305
270 err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base); 306 err = of_property_read_u32(np, "reg", &rtcdrv->rtc_base);
271 if (err) { 307 if (err) {
272 dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n"); 308 dev_err(&pdev->dev, "unable to find base address of rtc node in dtb\n");
@@ -286,14 +322,6 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
286 rtc_div = ((32768 / RTC_HZ) / 2) - 1; 322 rtc_div = ((32768 / RTC_HZ) / 2) - 1;
287 sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV); 323 sirfsoc_rtc_iobrg_writel(rtc_div, rtcdrv->rtc_base + RTC_DIV);
288 324
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 */ 325 /* 0x3 -> RTC_CLK */
298 sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK, 326 sirfsoc_rtc_iobrg_writel(SIRFSOC_RTC_CLK,
299 rtcdrv->rtc_base + RTC_CLOCK_SWITCH); 327 rtcdrv->rtc_base + RTC_CLOCK_SWITCH);
@@ -308,6 +336,14 @@ static int sirfsoc_rtc_probe(struct platform_device *pdev)
308 rtcdrv->overflow_rtc = 336 rtcdrv->overflow_rtc =
309 sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE); 337 sirfsoc_rtc_iobrg_readl(rtcdrv->rtc_base + RTC_SW_VALUE);
310 338
339 rtcdrv->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
340 &sirfsoc_rtc_ops, THIS_MODULE);
341 if (IS_ERR(rtcdrv->rtc)) {
342 err = PTR_ERR(rtcdrv->rtc);
343 dev_err(&pdev->dev, "can't register RTC device\n");
344 return err;
345 }
346
311 rtcdrv->irq = platform_get_irq(pdev, 0); 347 rtcdrv->irq = platform_get_irq(pdev, 0);
312 err = devm_request_irq( 348 err = devm_request_irq(
313 &pdev->dev, 349 &pdev->dev,