diff options
Diffstat (limited to 'drivers/rtc/rtc-spear.c')
-rw-r--r-- | drivers/rtc/rtc-spear.c | 99 |
1 files changed, 34 insertions, 65 deletions
diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index bb507d23f6ce..a18c3192ed40 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c | |||
@@ -351,7 +351,7 @@ static struct rtc_class_ops spear_rtc_ops = { | |||
351 | .alarm_irq_enable = spear_alarm_irq_enable, | 351 | .alarm_irq_enable = spear_alarm_irq_enable, |
352 | }; | 352 | }; |
353 | 353 | ||
354 | static int __devinit spear_rtc_probe(struct platform_device *pdev) | 354 | static int spear_rtc_probe(struct platform_device *pdev) |
355 | { | 355 | { |
356 | struct resource *res; | 356 | struct resource *res; |
357 | struct spear_rtc_config *config; | 357 | struct spear_rtc_config *config; |
@@ -363,35 +363,40 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) | |||
363 | dev_err(&pdev->dev, "no resource defined\n"); | 363 | dev_err(&pdev->dev, "no resource defined\n"); |
364 | return -EBUSY; | 364 | return -EBUSY; |
365 | } | 365 | } |
366 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
367 | dev_err(&pdev->dev, "rtc region already claimed\n"); | ||
368 | return -EBUSY; | ||
369 | } | ||
370 | 366 | ||
371 | config = kzalloc(sizeof(*config), GFP_KERNEL); | 367 | config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL); |
372 | if (!config) { | 368 | if (!config) { |
373 | dev_err(&pdev->dev, "out of memory\n"); | 369 | dev_err(&pdev->dev, "out of memory\n"); |
374 | status = -ENOMEM; | 370 | return -ENOMEM; |
375 | goto err_release_region; | ||
376 | } | 371 | } |
377 | 372 | ||
378 | config->clk = clk_get(&pdev->dev, NULL); | 373 | /* alarm irqs */ |
379 | if (IS_ERR(config->clk)) { | 374 | irq = platform_get_irq(pdev, 0); |
380 | status = PTR_ERR(config->clk); | 375 | if (irq < 0) { |
381 | goto err_kfree; | 376 | dev_err(&pdev->dev, "no update irq?\n"); |
377 | return irq; | ||
382 | } | 378 | } |
383 | 379 | ||
384 | status = clk_enable(config->clk); | 380 | status = devm_request_irq(&pdev->dev, irq, spear_rtc_irq, 0, pdev->name, |
385 | if (status < 0) | 381 | config); |
386 | goto err_clk_put; | 382 | if (status) { |
387 | 383 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already claimed\n", | |
388 | config->ioaddr = ioremap(res->start, resource_size(res)); | 384 | irq); |
389 | if (!config->ioaddr) { | 385 | return status; |
390 | dev_err(&pdev->dev, "ioremap fail\n"); | ||
391 | status = -ENOMEM; | ||
392 | goto err_disable_clock; | ||
393 | } | 386 | } |
394 | 387 | ||
388 | config->ioaddr = devm_ioremap_resource(&pdev->dev, res); | ||
389 | if (IS_ERR(config->ioaddr)) | ||
390 | return PTR_ERR(config->ioaddr); | ||
391 | |||
392 | config->clk = devm_clk_get(&pdev->dev, NULL); | ||
393 | if (IS_ERR(config->clk)) | ||
394 | return PTR_ERR(config->clk); | ||
395 | |||
396 | status = clk_prepare_enable(config->clk); | ||
397 | if (status < 0) | ||
398 | return status; | ||
399 | |||
395 | spin_lock_init(&config->lock); | 400 | spin_lock_init(&config->lock); |
396 | platform_set_drvdata(pdev, config); | 401 | platform_set_drvdata(pdev, config); |
397 | 402 | ||
@@ -401,67 +406,31 @@ static int __devinit spear_rtc_probe(struct platform_device *pdev) | |||
401 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", | 406 | dev_err(&pdev->dev, "can't register RTC device, err %ld\n", |
402 | PTR_ERR(config->rtc)); | 407 | PTR_ERR(config->rtc)); |
403 | status = PTR_ERR(config->rtc); | 408 | status = PTR_ERR(config->rtc); |
404 | goto err_iounmap; | 409 | goto err_disable_clock; |
405 | } | ||
406 | |||
407 | /* alarm irqs */ | ||
408 | irq = platform_get_irq(pdev, 0); | ||
409 | if (irq < 0) { | ||
410 | dev_err(&pdev->dev, "no update irq?\n"); | ||
411 | status = irq; | ||
412 | goto err_clear_platdata; | ||
413 | } | 410 | } |
414 | 411 | ||
415 | status = request_irq(irq, spear_rtc_irq, 0, pdev->name, config); | 412 | config->rtc->uie_unsupported = 1; |
416 | if (status) { | ||
417 | dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \ | ||
418 | claimed\n", irq); | ||
419 | goto err_clear_platdata; | ||
420 | } | ||
421 | 413 | ||
422 | if (!device_can_wakeup(&pdev->dev)) | 414 | if (!device_can_wakeup(&pdev->dev)) |
423 | device_init_wakeup(&pdev->dev, 1); | 415 | device_init_wakeup(&pdev->dev, 1); |
424 | 416 | ||
425 | return 0; | 417 | return 0; |
426 | 418 | ||
427 | err_clear_platdata: | ||
428 | platform_set_drvdata(pdev, NULL); | ||
429 | rtc_device_unregister(config->rtc); | ||
430 | err_iounmap: | ||
431 | iounmap(config->ioaddr); | ||
432 | err_disable_clock: | 419 | err_disable_clock: |
433 | clk_disable(config->clk); | 420 | platform_set_drvdata(pdev, NULL); |
434 | err_clk_put: | 421 | clk_disable_unprepare(config->clk); |
435 | clk_put(config->clk); | ||
436 | err_kfree: | ||
437 | kfree(config); | ||
438 | err_release_region: | ||
439 | release_mem_region(res->start, resource_size(res)); | ||
440 | 422 | ||
441 | return status; | 423 | return status; |
442 | } | 424 | } |
443 | 425 | ||
444 | static int __devexit spear_rtc_remove(struct platform_device *pdev) | 426 | static int spear_rtc_remove(struct platform_device *pdev) |
445 | { | 427 | { |
446 | struct spear_rtc_config *config = platform_get_drvdata(pdev); | 428 | struct spear_rtc_config *config = platform_get_drvdata(pdev); |
447 | int irq; | ||
448 | struct resource *res; | ||
449 | 429 | ||
450 | /* leave rtc running, but disable irqs */ | 430 | rtc_device_unregister(config->rtc); |
451 | spear_rtc_disable_interrupt(config); | 431 | spear_rtc_disable_interrupt(config); |
432 | clk_disable_unprepare(config->clk); | ||
452 | device_init_wakeup(&pdev->dev, 0); | 433 | device_init_wakeup(&pdev->dev, 0); |
453 | irq = platform_get_irq(pdev, 0); | ||
454 | if (irq) | ||
455 | free_irq(irq, pdev); | ||
456 | clk_disable(config->clk); | ||
457 | clk_put(config->clk); | ||
458 | iounmap(config->ioaddr); | ||
459 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
460 | if (res) | ||
461 | release_mem_region(res->start, resource_size(res)); | ||
462 | platform_set_drvdata(pdev, NULL); | ||
463 | rtc_device_unregister(config->rtc); | ||
464 | kfree(config); | ||
465 | 434 | ||
466 | return 0; | 435 | return 0; |
467 | } | 436 | } |
@@ -528,7 +497,7 @@ MODULE_DEVICE_TABLE(of, spear_rtc_id_table); | |||
528 | 497 | ||
529 | static struct platform_driver spear_rtc_driver = { | 498 | static struct platform_driver spear_rtc_driver = { |
530 | .probe = spear_rtc_probe, | 499 | .probe = spear_rtc_probe, |
531 | .remove = __devexit_p(spear_rtc_remove), | 500 | .remove = spear_rtc_remove, |
532 | .suspend = spear_rtc_suspend, | 501 | .suspend = spear_rtc_suspend, |
533 | .resume = spear_rtc_resume, | 502 | .resume = spear_rtc_resume, |
534 | .shutdown = spear_rtc_shutdown, | 503 | .shutdown = spear_rtc_shutdown, |