diff options
author | David Brownell <david-b@pacbell.net> | 2007-02-20 16:58:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-20 20:10:15 -0500 |
commit | 5d4675a811fb71fd922109d7ebae3f987401ace1 (patch) | |
tree | 8e03c86e64797963ef625ee9174147dfbc6bc24b /drivers/rtc | |
parent | 32b49da46caa8067ea47eea8b7aee6559e452125 (diff) |
[PATCH] at91_rtc updates
Various bug fixes to the at91rm9200 RTC:
- alarm: setalarm() should pay attention to the "enabled" flag
- init: cleaner handling of the wakeup flags, which cpu init should
really have set up. Doing it here is just a workaround.
- linkage: since the at91_rtc driver probe() routine is in the init
section, it should use platform_driver_probe() instead of leaving
that pointer around in the driver struct after init section removal.
- linkage: likewise, remove() belongs in the exit section.
Among other things, the init and alarm changes ensure that this driver
handles the new sysfs "wakealarm" attribute properly.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-at91rm9200.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index a724ab49a797..ac0e68e2f025 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c | |||
@@ -164,6 +164,7 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
164 | tm.tm_min = alrm->time.tm_min; | 164 | tm.tm_min = alrm->time.tm_min; |
165 | tm.tm_sec = alrm->time.tm_sec; | 165 | tm.tm_sec = alrm->time.tm_sec; |
166 | 166 | ||
167 | at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); | ||
167 | at91_sys_write(AT91_RTC_TIMALR, | 168 | at91_sys_write(AT91_RTC_TIMALR, |
168 | BIN2BCD(tm.tm_sec) << 0 | 169 | BIN2BCD(tm.tm_sec) << 0 |
169 | | BIN2BCD(tm.tm_min) << 8 | 170 | | BIN2BCD(tm.tm_min) << 8 |
@@ -174,6 +175,9 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
174 | | BIN2BCD(tm.tm_mday) << 24 | 175 | | BIN2BCD(tm.tm_mday) << 24 |
175 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); | 176 | | AT91_RTC_DATEEN | AT91_RTC_MTHEN); |
176 | 177 | ||
178 | if (alrm->enabled) | ||
179 | at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); | ||
180 | |||
177 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, | 181 | pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, |
178 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, | 182 | at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, |
179 | tm.tm_min, tm.tm_sec); | 183 | tm.tm_min, tm.tm_sec); |
@@ -303,6 +307,12 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
303 | return ret; | 307 | return ret; |
304 | } | 308 | } |
305 | 309 | ||
310 | /* cpu init code should really have flagged this device as | ||
311 | * being wake-capable; if it didn't, do that here. | ||
312 | */ | ||
313 | if (!device_can_wakeup(&pdev->dev)) | ||
314 | device_init_wakeup(&pdev->dev, 1); | ||
315 | |||
306 | rtc = rtc_device_register(pdev->name, &pdev->dev, | 316 | rtc = rtc_device_register(pdev->name, &pdev->dev, |
307 | &at91_rtc_ops, THIS_MODULE); | 317 | &at91_rtc_ops, THIS_MODULE); |
308 | if (IS_ERR(rtc)) { | 318 | if (IS_ERR(rtc)) { |
@@ -310,7 +320,6 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
310 | return PTR_ERR(rtc); | 320 | return PTR_ERR(rtc); |
311 | } | 321 | } |
312 | platform_set_drvdata(pdev, rtc); | 322 | platform_set_drvdata(pdev, rtc); |
313 | device_init_wakeup(&pdev->dev, 1); | ||
314 | 323 | ||
315 | printk(KERN_INFO "AT91 Real Time Clock driver.\n"); | 324 | printk(KERN_INFO "AT91 Real Time Clock driver.\n"); |
316 | return 0; | 325 | return 0; |
@@ -319,7 +328,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) | |||
319 | /* | 328 | /* |
320 | * Disable and remove the RTC driver | 329 | * Disable and remove the RTC driver |
321 | */ | 330 | */ |
322 | static int __devexit at91_rtc_remove(struct platform_device *pdev) | 331 | static int __exit at91_rtc_remove(struct platform_device *pdev) |
323 | { | 332 | { |
324 | struct rtc_device *rtc = platform_get_drvdata(pdev); | 333 | struct rtc_device *rtc = platform_get_drvdata(pdev); |
325 | 334 | ||
@@ -331,7 +340,6 @@ static int __devexit at91_rtc_remove(struct platform_device *pdev) | |||
331 | 340 | ||
332 | rtc_device_unregister(rtc); | 341 | rtc_device_unregister(rtc); |
333 | platform_set_drvdata(pdev, NULL); | 342 | platform_set_drvdata(pdev, NULL); |
334 | device_init_wakeup(&pdev->dev, 0); | ||
335 | 343 | ||
336 | return 0; | 344 | return 0; |
337 | } | 345 | } |
@@ -404,8 +412,7 @@ static int at91_rtc_resume(struct platform_device *pdev) | |||
404 | #endif | 412 | #endif |
405 | 413 | ||
406 | static struct platform_driver at91_rtc_driver = { | 414 | static struct platform_driver at91_rtc_driver = { |
407 | .probe = at91_rtc_probe, | 415 | .remove = __exit_p(at91_rtc_remove), |
408 | .remove = at91_rtc_remove, | ||
409 | .suspend = at91_rtc_suspend, | 416 | .suspend = at91_rtc_suspend, |
410 | .resume = at91_rtc_resume, | 417 | .resume = at91_rtc_resume, |
411 | .driver = { | 418 | .driver = { |
@@ -416,7 +423,7 @@ static struct platform_driver at91_rtc_driver = { | |||
416 | 423 | ||
417 | static int __init at91_rtc_init(void) | 424 | static int __init at91_rtc_init(void) |
418 | { | 425 | { |
419 | return platform_driver_register(&at91_rtc_driver); | 426 | return platform_driver_probe(&at91_rtc_driver, at91_rtc_probe); |
420 | } | 427 | } |
421 | 428 | ||
422 | static void __exit at91_rtc_exit(void) | 429 | static void __exit at91_rtc_exit(void) |