aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-mrst.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-mrst.c')
-rw-r--r--drivers/rtc/rtc-mrst.c79
1 files changed, 25 insertions, 54 deletions
diff --git a/drivers/rtc/rtc-mrst.c b/drivers/rtc/rtc-mrst.c
index bcd0cf63eb16..b2f096871a97 100644
--- a/drivers/rtc/rtc-mrst.c
+++ b/drivers/rtc/rtc-mrst.c
@@ -62,6 +62,17 @@ static inline int is_intr(u8 rtc_intr)
62 return rtc_intr & RTC_IRQMASK; 62 return rtc_intr & RTC_IRQMASK;
63} 63}
64 64
65static inline unsigned char vrtc_is_updating(void)
66{
67 unsigned char uip;
68 unsigned long flags;
69
70 spin_lock_irqsave(&rtc_lock, flags);
71 uip = (vrtc_cmos_read(RTC_FREQ_SELECT) & RTC_UIP);
72 spin_unlock_irqrestore(&rtc_lock, flags);
73 return uip;
74}
75
65/* 76/*
66 * rtc_time's year contains the increment over 1900, but vRTC's YEAR 77 * rtc_time's year contains the increment over 1900, but vRTC's YEAR
67 * register can't be programmed to value larger than 0x64, so vRTC 78 * register can't be programmed to value larger than 0x64, so vRTC
@@ -76,7 +87,7 @@ static int mrst_read_time(struct device *dev, struct rtc_time *time)
76{ 87{
77 unsigned long flags; 88 unsigned long flags;
78 89
79 if (rtc_is_updating()) 90 if (vrtc_is_updating())
80 mdelay(20); 91 mdelay(20);
81 92
82 spin_lock_irqsave(&rtc_lock, flags); 93 spin_lock_irqsave(&rtc_lock, flags);
@@ -236,61 +247,21 @@ static int mrst_set_alarm(struct device *dev, struct rtc_wkalrm *t)
236 return 0; 247 return 0;
237} 248}
238 249
239static int mrst_irq_set_state(struct device *dev, int enabled) 250/* Currently, the vRTC doesn't support UIE ON/OFF */
251static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
240{ 252{
241 struct mrst_rtc *mrst = dev_get_drvdata(dev); 253 struct mrst_rtc *mrst = dev_get_drvdata(dev);
242 unsigned long flags; 254 unsigned long flags;
243 255
244 if (!mrst->irq)
245 return -ENXIO;
246
247 spin_lock_irqsave(&rtc_lock, flags); 256 spin_lock_irqsave(&rtc_lock, flags);
248
249 if (enabled) 257 if (enabled)
250 mrst_irq_enable(mrst, RTC_PIE); 258 mrst_irq_enable(mrst, RTC_AIE);
251 else 259 else
252 mrst_irq_disable(mrst, RTC_PIE);
253
254 spin_unlock_irqrestore(&rtc_lock, flags);
255 return 0;
256}
257
258#if defined(CONFIG_RTC_INTF_DEV) || defined(CONFIG_RTC_INTF_DEV_MODULE)
259
260/* Currently, the vRTC doesn't support UIE ON/OFF */
261static int
262mrst_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
263{
264 struct mrst_rtc *mrst = dev_get_drvdata(dev);
265 unsigned long flags;
266
267 switch (cmd) {
268 case RTC_AIE_OFF:
269 case RTC_AIE_ON:
270 if (!mrst->irq)
271 return -EINVAL;
272 break;
273 default:
274 /* PIE ON/OFF is handled by mrst_irq_set_state() */
275 return -ENOIOCTLCMD;
276 }
277
278 spin_lock_irqsave(&rtc_lock, flags);
279 switch (cmd) {
280 case RTC_AIE_OFF: /* alarm off */
281 mrst_irq_disable(mrst, RTC_AIE); 260 mrst_irq_disable(mrst, RTC_AIE);
282 break;
283 case RTC_AIE_ON: /* alarm on */
284 mrst_irq_enable(mrst, RTC_AIE);
285 break;
286 }
287 spin_unlock_irqrestore(&rtc_lock, flags); 261 spin_unlock_irqrestore(&rtc_lock, flags);
288 return 0; 262 return 0;
289} 263}
290 264
291#else
292#define mrst_rtc_ioctl NULL
293#endif
294 265
295#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE) 266#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
296 267
@@ -317,13 +288,12 @@ static int mrst_procfs(struct device *dev, struct seq_file *seq)
317#endif 288#endif
318 289
319static const struct rtc_class_ops mrst_rtc_ops = { 290static const struct rtc_class_ops mrst_rtc_ops = {
320 .ioctl = mrst_rtc_ioctl,
321 .read_time = mrst_read_time, 291 .read_time = mrst_read_time,
322 .set_time = mrst_set_time, 292 .set_time = mrst_set_time,
323 .read_alarm = mrst_read_alarm, 293 .read_alarm = mrst_read_alarm,
324 .set_alarm = mrst_set_alarm, 294 .set_alarm = mrst_set_alarm,
325 .proc = mrst_procfs, 295 .proc = mrst_procfs,
326 .irq_set_state = mrst_irq_set_state, 296 .alarm_irq_enable = mrst_rtc_alarm_irq_enable,
327}; 297};
328 298
329static struct mrst_rtc mrst_rtc; 299static struct mrst_rtc mrst_rtc;
@@ -349,7 +319,7 @@ static irqreturn_t mrst_rtc_irq(int irq, void *p)
349 return IRQ_NONE; 319 return IRQ_NONE;
350} 320}
351 321
352static int __init 322static int __devinit
353vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq) 323vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
354{ 324{
355 int retval = 0; 325 int retval = 0;
@@ -372,6 +342,8 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
372 342
373 mrst_rtc.irq = rtc_irq; 343 mrst_rtc.irq = rtc_irq;
374 mrst_rtc.iomem = iomem; 344 mrst_rtc.iomem = iomem;
345 mrst_rtc.dev = dev;
346 dev_set_drvdata(dev, &mrst_rtc);
375 347
376 mrst_rtc.rtc = rtc_device_register(driver_name, dev, 348 mrst_rtc.rtc = rtc_device_register(driver_name, dev,
377 &mrst_rtc_ops, THIS_MODULE); 349 &mrst_rtc_ops, THIS_MODULE);
@@ -380,8 +352,6 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
380 goto cleanup0; 352 goto cleanup0;
381 } 353 }
382 354
383 mrst_rtc.dev = dev;
384 dev_set_drvdata(dev, &mrst_rtc);
385 rename_region(iomem, dev_name(&mrst_rtc.rtc->dev)); 355 rename_region(iomem, dev_name(&mrst_rtc.rtc->dev));
386 356
387 spin_lock_irq(&rtc_lock); 357 spin_lock_irq(&rtc_lock);
@@ -406,9 +376,10 @@ vrtc_mrst_do_probe(struct device *dev, struct resource *iomem, int rtc_irq)
406 return 0; 376 return 0;
407 377
408cleanup1: 378cleanup1:
409 mrst_rtc.dev = NULL;
410 rtc_device_unregister(mrst_rtc.rtc); 379 rtc_device_unregister(mrst_rtc.rtc);
411cleanup0: 380cleanup0:
381 dev_set_drvdata(dev, NULL);
382 mrst_rtc.dev = NULL;
412 release_region(iomem->start, iomem->end + 1 - iomem->start); 383 release_region(iomem->start, iomem->end + 1 - iomem->start);
413 dev_err(dev, "rtc-mrst: unable to initialise\n"); 384 dev_err(dev, "rtc-mrst: unable to initialise\n");
414 return retval; 385 return retval;
@@ -421,7 +392,7 @@ static void rtc_mrst_do_shutdown(void)
421 spin_unlock_irq(&rtc_lock); 392 spin_unlock_irq(&rtc_lock);
422} 393}
423 394
424static void __exit rtc_mrst_do_remove(struct device *dev) 395static void __devexit rtc_mrst_do_remove(struct device *dev)
425{ 396{
426 struct mrst_rtc *mrst = dev_get_drvdata(dev); 397 struct mrst_rtc *mrst = dev_get_drvdata(dev);
427 struct resource *iomem; 398 struct resource *iomem;
@@ -530,14 +501,14 @@ static inline int mrst_poweroff(struct device *dev)
530 501
531#endif 502#endif
532 503
533static int __init vrtc_mrst_platform_probe(struct platform_device *pdev) 504static int __devinit vrtc_mrst_platform_probe(struct platform_device *pdev)
534{ 505{
535 return vrtc_mrst_do_probe(&pdev->dev, 506 return vrtc_mrst_do_probe(&pdev->dev,
536 platform_get_resource(pdev, IORESOURCE_MEM, 0), 507 platform_get_resource(pdev, IORESOURCE_MEM, 0),
537 platform_get_irq(pdev, 0)); 508 platform_get_irq(pdev, 0));
538} 509}
539 510
540static int __exit vrtc_mrst_platform_remove(struct platform_device *pdev) 511static int __devexit vrtc_mrst_platform_remove(struct platform_device *pdev)
541{ 512{
542 rtc_mrst_do_remove(&pdev->dev); 513 rtc_mrst_do_remove(&pdev->dev);
543 return 0; 514 return 0;
@@ -555,7 +526,7 @@ MODULE_ALIAS("platform:vrtc_mrst");
555 526
556static struct platform_driver vrtc_mrst_platform_driver = { 527static struct platform_driver vrtc_mrst_platform_driver = {
557 .probe = vrtc_mrst_platform_probe, 528 .probe = vrtc_mrst_platform_probe,
558 .remove = __exit_p(vrtc_mrst_platform_remove), 529 .remove = __devexit_p(vrtc_mrst_platform_remove),
559 .shutdown = vrtc_mrst_platform_shutdown, 530 .shutdown = vrtc_mrst_platform_shutdown,
560 .driver = { 531 .driver = {
561 .name = (char *) driver_name, 532 .name = (char *) driver_name,