aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc/rtc-at91sam9.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-at91sam9.c')
-rw-r--r--drivers/rtc/rtc-at91sam9.c85
1 files changed, 28 insertions, 57 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c
index 274a0aafe42b..831868904e02 100644
--- a/drivers/rtc/rtc-at91sam9.c
+++ b/drivers/rtc/rtc-at91sam9.c
@@ -57,6 +57,7 @@ struct sam9_rtc {
57 void __iomem *rtt; 57 void __iomem *rtt;
58 struct rtc_device *rtcdev; 58 struct rtc_device *rtcdev;
59 u32 imr; 59 u32 imr;
60 void __iomem *gpbr;
60}; 61};
61 62
62#define rtt_readl(rtc, field) \ 63#define rtt_readl(rtc, field) \
@@ -65,9 +66,9 @@ struct sam9_rtc {
65 __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) 66 __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field)
66 67
67#define gpbr_readl(rtc) \ 68#define gpbr_readl(rtc) \
68 at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) 69 __raw_readl((rtc)->gpbr)
69#define gpbr_writel(rtc, val) \ 70#define gpbr_writel(rtc, val) \
70 at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) 71 __raw_writel((val), (rtc)->gpbr)
71 72
72/* 73/*
73 * Read current time and date in RTC 74 * Read current time and date in RTC
@@ -287,16 +288,19 @@ static const struct rtc_class_ops at91_rtc_ops = {
287/* 288/*
288 * Initialize and install RTC driver 289 * Initialize and install RTC driver
289 */ 290 */
290static int __init at91_rtc_probe(struct platform_device *pdev) 291static int __devinit at91_rtc_probe(struct platform_device *pdev)
291{ 292{
292 struct resource *r; 293 struct resource *r, *r_gpbr;
293 struct sam9_rtc *rtc; 294 struct sam9_rtc *rtc;
294 int ret; 295 int ret;
295 u32 mr; 296 u32 mr;
296 297
297 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 298 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
298 if (!r) 299 r_gpbr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
300 if (!r || !r_gpbr) {
301 dev_err(&pdev->dev, "need 2 ressources\n");
299 return -ENODEV; 302 return -ENODEV;
303 }
300 304
301 rtc = kzalloc(sizeof *rtc, GFP_KERNEL); 305 rtc = kzalloc(sizeof *rtc, GFP_KERNEL);
302 if (!rtc) 306 if (!rtc)
@@ -314,6 +318,13 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
314 goto fail; 318 goto fail;
315 } 319 }
316 320
321 rtc->gpbr = ioremap(r_gpbr->start, resource_size(r_gpbr));
322 if (!rtc->gpbr) {
323 dev_err(&pdev->dev, "failed to map gpbr registers, aborting.\n");
324 ret = -ENOMEM;
325 goto fail_gpbr;
326 }
327
317 mr = rtt_readl(rtc, MR); 328 mr = rtt_readl(rtc, MR);
318 329
319 /* unless RTT is counting at 1 Hz, re-initialize it */ 330 /* unless RTT is counting at 1 Hz, re-initialize it */
@@ -340,7 +351,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
340 if (ret) { 351 if (ret) {
341 dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); 352 dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS);
342 rtc_device_unregister(rtc->rtcdev); 353 rtc_device_unregister(rtc->rtcdev);
343 goto fail; 354 goto fail_register;
344 } 355 }
345 356
346 /* NOTE: sam9260 rev A silicon has a ROM bug which resets the 357 /* NOTE: sam9260 rev A silicon has a ROM bug which resets the
@@ -356,6 +367,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev)
356 return 0; 367 return 0;
357 368
358fail_register: 369fail_register:
370 iounmap(rtc->gpbr);
371fail_gpbr:
359 iounmap(rtc->rtt); 372 iounmap(rtc->rtt);
360fail: 373fail:
361 platform_set_drvdata(pdev, NULL); 374 platform_set_drvdata(pdev, NULL);
@@ -366,7 +379,7 @@ fail:
366/* 379/*
367 * Disable and remove the RTC driver 380 * Disable and remove the RTC driver
368 */ 381 */
369static int __exit at91_rtc_remove(struct platform_device *pdev) 382static int __devexit at91_rtc_remove(struct platform_device *pdev)
370{ 383{
371 struct sam9_rtc *rtc = platform_get_drvdata(pdev); 384 struct sam9_rtc *rtc = platform_get_drvdata(pdev);
372 u32 mr = rtt_readl(rtc, MR); 385 u32 mr = rtt_readl(rtc, MR);
@@ -377,6 +390,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
377 390
378 rtc_device_unregister(rtc->rtcdev); 391 rtc_device_unregister(rtc->rtcdev);
379 392
393 iounmap(rtc->gpbr);
380 iounmap(rtc->rtt); 394 iounmap(rtc->rtt);
381 platform_set_drvdata(pdev, NULL); 395 platform_set_drvdata(pdev, NULL);
382 kfree(rtc); 396 kfree(rtc);
@@ -440,63 +454,20 @@ static int at91_rtc_resume(struct platform_device *pdev)
440#endif 454#endif
441 455
442static struct platform_driver at91_rtc_driver = { 456static struct platform_driver at91_rtc_driver = {
443 .driver.name = "rtc-at91sam9", 457 .probe = at91_rtc_probe,
444 .driver.owner = THIS_MODULE, 458 .remove = __devexit_p(at91_rtc_remove),
445 .remove = __exit_p(at91_rtc_remove),
446 .shutdown = at91_rtc_shutdown, 459 .shutdown = at91_rtc_shutdown,
447 .suspend = at91_rtc_suspend, 460 .suspend = at91_rtc_suspend,
448 .resume = at91_rtc_resume, 461 .resume = at91_rtc_resume,
462 .driver = {
463 .name = "rtc-at91sam9",
464 .owner = THIS_MODULE,
465 },
449}; 466};
450 467
451/* Chips can have more than one RTT module, and they can be used for more
452 * than just RTCs. So we can't just register as "the" RTT driver.
453 *
454 * A normal approach in such cases is to create a library to allocate and
455 * free the modules. Here we just use bus_find_device() as like such a
456 * library, binding directly ... no runtime "library" footprint is needed.
457 */
458static int __init at91_rtc_match(struct device *dev, void *v)
459{
460 struct platform_device *pdev = to_platform_device(dev);
461 int ret;
462
463 /* continue searching if this isn't the RTT we need */
464 if (strcmp("at91_rtt", pdev->name) != 0
465 || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT)
466 goto fail;
467
468 /* else we found it ... but fail unless we can bind to the RTC driver */
469 if (dev->driver) {
470 dev_dbg(dev, "busy, can't use as RTC!\n");
471 goto fail;
472 }
473 dev->driver = &at91_rtc_driver.driver;
474 if (device_attach(dev) == 0) {
475 dev_dbg(dev, "can't attach RTC!\n");
476 goto fail;
477 }
478 ret = at91_rtc_probe(pdev);
479 if (ret == 0)
480 return true;
481
482 dev_dbg(dev, "RTC probe err %d!\n", ret);
483fail:
484 return false;
485}
486
487static int __init at91_rtc_init(void) 468static int __init at91_rtc_init(void)
488{ 469{
489 int status; 470 return platform_driver_register(&at91_rtc_driver);
490 struct device *rtc;
491
492 status = platform_driver_register(&at91_rtc_driver);
493 if (status)
494 return status;
495 rtc = bus_find_device(&platform_bus_type, NULL,
496 NULL, at91_rtc_match);
497 if (!rtc)
498 platform_driver_unregister(&at91_rtc_driver);
499 return rtc ? 0 : -ENODEV;
500} 471}
501module_init(at91_rtc_init); 472module_init(at91_rtc_init);
502 473