diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2012-02-15 07:51:37 -0500 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-02-23 08:57:57 -0500 |
commit | 205056a3ea33f5aca7adffa4584eb6572b1d3273 (patch) | |
tree | 1672d459205d815001b097ff951a55c8a1299b86 /drivers/rtc/rtc-at91sam9.c | |
parent | b55149529d265718a989b67468c4f03de0d3af7a (diff) |
ARM: at91/rtc-at91sam9: each SoC can select the RTT device to use
For the RTT as RTC driver rtc-at91sam9, the platform_device structure
is filled during SoC initialization. This will allow to convert this
RTC driver as a standard platform driver.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Diffstat (limited to 'drivers/rtc/rtc-at91sam9.c')
-rw-r--r-- | drivers/rtc/rtc-at91sam9.c | 61 |
1 files changed, 9 insertions, 52 deletions
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index a3ad957507dc..65896a3a352f 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -287,7 +287,7 @@ static const struct rtc_class_ops at91_rtc_ops = { | |||
287 | /* | 287 | /* |
288 | * Initialize and install RTC driver | 288 | * Initialize and install RTC driver |
289 | */ | 289 | */ |
290 | static int __init at91_rtc_probe(struct platform_device *pdev) | 290 | static int __devinit at91_rtc_probe(struct platform_device *pdev) |
291 | { | 291 | { |
292 | struct resource *r; | 292 | struct resource *r; |
293 | struct sam9_rtc *rtc; | 293 | struct sam9_rtc *rtc; |
@@ -360,7 +360,7 @@ fail: | |||
360 | /* | 360 | /* |
361 | * Disable and remove the RTC driver | 361 | * Disable and remove the RTC driver |
362 | */ | 362 | */ |
363 | static int __exit at91_rtc_remove(struct platform_device *pdev) | 363 | static int __devexit at91_rtc_remove(struct platform_device *pdev) |
364 | { | 364 | { |
365 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | 365 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); |
366 | u32 mr = rtt_readl(rtc, MR); | 366 | u32 mr = rtt_readl(rtc, MR); |
@@ -433,63 +433,20 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
433 | #endif | 433 | #endif |
434 | 434 | ||
435 | static struct platform_driver at91_rtc_driver = { | 435 | static struct platform_driver at91_rtc_driver = { |
436 | .driver.name = "rtc-at91sam9", | 436 | .probe = at91_rtc_probe, |
437 | .driver.owner = THIS_MODULE, | 437 | .remove = __devexit_p(at91_rtc_remove), |
438 | .remove = __exit_p(at91_rtc_remove), | ||
439 | .shutdown = at91_rtc_shutdown, | 438 | .shutdown = at91_rtc_shutdown, |
440 | .suspend = at91_rtc_suspend, | 439 | .suspend = at91_rtc_suspend, |
441 | .resume = at91_rtc_resume, | 440 | .resume = at91_rtc_resume, |
441 | .driver = { | ||
442 | .name = "rtc-at91sam9", | ||
443 | .owner = THIS_MODULE, | ||
444 | }, | ||
442 | }; | 445 | }; |
443 | 446 | ||
444 | /* Chips can have more than one RTT module, and they can be used for more | ||
445 | * than just RTCs. So we can't just register as "the" RTT driver. | ||
446 | * | ||
447 | * A normal approach in such cases is to create a library to allocate and | ||
448 | * free the modules. Here we just use bus_find_device() as like such a | ||
449 | * library, binding directly ... no runtime "library" footprint is needed. | ||
450 | */ | ||
451 | static int __init at91_rtc_match(struct device *dev, void *v) | ||
452 | { | ||
453 | struct platform_device *pdev = to_platform_device(dev); | ||
454 | int ret; | ||
455 | |||
456 | /* continue searching if this isn't the RTT we need */ | ||
457 | if (strcmp("at91_rtt", pdev->name) != 0 | ||
458 | || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) | ||
459 | goto fail; | ||
460 | |||
461 | /* else we found it ... but fail unless we can bind to the RTC driver */ | ||
462 | if (dev->driver) { | ||
463 | dev_dbg(dev, "busy, can't use as RTC!\n"); | ||
464 | goto fail; | ||
465 | } | ||
466 | dev->driver = &at91_rtc_driver.driver; | ||
467 | if (device_attach(dev) == 0) { | ||
468 | dev_dbg(dev, "can't attach RTC!\n"); | ||
469 | goto fail; | ||
470 | } | ||
471 | ret = at91_rtc_probe(pdev); | ||
472 | if (ret == 0) | ||
473 | return true; | ||
474 | |||
475 | dev_dbg(dev, "RTC probe err %d!\n", ret); | ||
476 | fail: | ||
477 | return false; | ||
478 | } | ||
479 | |||
480 | static int __init at91_rtc_init(void) | 447 | static int __init at91_rtc_init(void) |
481 | { | 448 | { |
482 | int status; | 449 | return platform_driver_register(&at91_rtc_driver); |
483 | struct device *rtc; | ||
484 | |||
485 | status = platform_driver_register(&at91_rtc_driver); | ||
486 | if (status) | ||
487 | return status; | ||
488 | rtc = bus_find_device(&platform_bus_type, NULL, | ||
489 | NULL, at91_rtc_match); | ||
490 | if (!rtc) | ||
491 | platform_driver_unregister(&at91_rtc_driver); | ||
492 | return rtc ? 0 : -ENODEV; | ||
493 | } | 450 | } |
494 | module_init(at91_rtc_init); | 451 | module_init(at91_rtc_init); |
495 | 452 | ||