diff options
Diffstat (limited to 'drivers/rtc/rtc-mxc.c')
| -rw-r--r-- | drivers/rtc/rtc-mxc.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 6bd5072d4eb7..25ec921db07c 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| 13 | #include <linux/rtc.h> | 13 | #include <linux/rtc.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 16 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
| 17 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
| @@ -378,29 +379,37 @@ static struct rtc_class_ops mxc_rtc_ops = { | |||
| 378 | 379 | ||
| 379 | static int __init mxc_rtc_probe(struct platform_device *pdev) | 380 | static int __init mxc_rtc_probe(struct platform_device *pdev) |
| 380 | { | 381 | { |
| 381 | struct clk *clk; | ||
| 382 | struct resource *res; | 382 | struct resource *res; |
| 383 | struct rtc_device *rtc; | 383 | struct rtc_device *rtc; |
| 384 | struct rtc_plat_data *pdata = NULL; | 384 | struct rtc_plat_data *pdata = NULL; |
| 385 | u32 reg; | 385 | u32 reg; |
| 386 | int ret, rate; | 386 | unsigned long rate; |
| 387 | int ret; | ||
| 387 | 388 | ||
| 388 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 389 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 389 | if (!res) | 390 | if (!res) |
| 390 | return -ENODEV; | 391 | return -ENODEV; |
| 391 | 392 | ||
| 392 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | 393 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
| 393 | if (!pdata) | 394 | if (!pdata) |
| 394 | return -ENOMEM; | 395 | return -ENOMEM; |
| 395 | 396 | ||
| 396 | pdata->ioaddr = ioremap(res->start, resource_size(res)); | 397 | if (!devm_request_mem_region(&pdev->dev, res->start, |
| 398 | resource_size(res), pdev->name)) | ||
| 399 | return -EBUSY; | ||
| 397 | 400 | ||
| 398 | clk = clk_get(&pdev->dev, "ckil"); | 401 | pdata->ioaddr = devm_ioremap(&pdev->dev, res->start, |
| 399 | if (IS_ERR(clk)) | 402 | resource_size(res)); |
| 400 | return PTR_ERR(clk); | ||
| 401 | 403 | ||
| 402 | rate = clk_get_rate(clk); | 404 | pdata->clk = clk_get(&pdev->dev, "rtc"); |
| 403 | clk_put(clk); | 405 | if (IS_ERR(pdata->clk)) { |
| 406 | dev_err(&pdev->dev, "unable to get clock!\n"); | ||
| 407 | ret = PTR_ERR(pdata->clk); | ||
| 408 | goto exit_free_pdata; | ||
| 409 | } | ||
| 410 | |||
| 411 | clk_enable(pdata->clk); | ||
| 412 | rate = clk_get_rate(pdata->clk); | ||
| 404 | 413 | ||
| 405 | if (rate == 32768) | 414 | if (rate == 32768) |
| 406 | reg = RTC_INPUT_CLK_32768HZ; | 415 | reg = RTC_INPUT_CLK_32768HZ; |
| @@ -409,10 +418,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
| 409 | else if (rate == 38400) | 418 | else if (rate == 38400) |
| 410 | reg = RTC_INPUT_CLK_38400HZ; | 419 | reg = RTC_INPUT_CLK_38400HZ; |
| 411 | else { | 420 | else { |
| 412 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", | 421 | dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); |
| 413 | clk_get_rate(clk)); | ||
| 414 | ret = -EINVAL; | 422 | ret = -EINVAL; |
| 415 | goto exit_free_pdata; | 423 | goto exit_put_clk; |
| 416 | } | 424 | } |
| 417 | 425 | ||
| 418 | reg |= RTC_ENABLE_BIT; | 426 | reg |= RTC_ENABLE_BIT; |
| @@ -420,18 +428,9 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
| 420 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { | 428 | if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { |
| 421 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); | 429 | dev_err(&pdev->dev, "hardware module can't be enabled!\n"); |
| 422 | ret = -EIO; | 430 | ret = -EIO; |
| 423 | goto exit_free_pdata; | 431 | goto exit_put_clk; |
| 424 | } | ||
| 425 | |||
| 426 | pdata->clk = clk_get(&pdev->dev, "rtc"); | ||
| 427 | if (IS_ERR(pdata->clk)) { | ||
| 428 | dev_err(&pdev->dev, "unable to get clock!\n"); | ||
| 429 | ret = PTR_ERR(pdata->clk); | ||
| 430 | goto exit_free_pdata; | ||
| 431 | } | 432 | } |
| 432 | 433 | ||
| 433 | clk_enable(pdata->clk); | ||
| 434 | |||
| 435 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | 434 | rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, |
| 436 | THIS_MODULE); | 435 | THIS_MODULE); |
| 437 | if (IS_ERR(rtc)) { | 436 | if (IS_ERR(rtc)) { |
| @@ -446,8 +445,8 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
| 446 | pdata->irq = platform_get_irq(pdev, 0); | 445 | pdata->irq = platform_get_irq(pdev, 0); |
| 447 | 446 | ||
| 448 | if (pdata->irq >= 0 && | 447 | if (pdata->irq >= 0 && |
| 449 | request_irq(pdata->irq, mxc_rtc_interrupt, IRQF_SHARED, | 448 | devm_request_irq(&pdev->dev, pdata->irq, mxc_rtc_interrupt, |
| 450 | pdev->name, pdev) < 0) { | 449 | IRQF_SHARED, pdev->name, pdev) < 0) { |
| 451 | dev_warn(&pdev->dev, "interrupt not available.\n"); | 450 | dev_warn(&pdev->dev, "interrupt not available.\n"); |
| 452 | pdata->irq = -1; | 451 | pdata->irq = -1; |
| 453 | } | 452 | } |
| @@ -455,10 +454,10 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) | |||
| 455 | return 0; | 454 | return 0; |
| 456 | 455 | ||
| 457 | exit_put_clk: | 456 | exit_put_clk: |
| 457 | clk_disable(pdata->clk); | ||
| 458 | clk_put(pdata->clk); | 458 | clk_put(pdata->clk); |
| 459 | 459 | ||
| 460 | exit_free_pdata: | 460 | exit_free_pdata: |
| 461 | kfree(pdata); | ||
| 462 | 461 | ||
| 463 | return ret; | 462 | return ret; |
| 464 | } | 463 | } |
| @@ -469,12 +468,8 @@ static int __exit mxc_rtc_remove(struct platform_device *pdev) | |||
| 469 | 468 | ||
| 470 | rtc_device_unregister(pdata->rtc); | 469 | rtc_device_unregister(pdata->rtc); |
| 471 | 470 | ||
| 472 | if (pdata->irq >= 0) | ||
| 473 | free_irq(pdata->irq, pdev); | ||
| 474 | |||
| 475 | clk_disable(pdata->clk); | 471 | clk_disable(pdata->clk); |
| 476 | clk_put(pdata->clk); | 472 | clk_put(pdata->clk); |
| 477 | kfree(pdata); | ||
| 478 | platform_set_drvdata(pdev, NULL); | 473 | platform_set_drvdata(pdev, NULL); |
| 479 | 474 | ||
| 480 | return 0; | 475 | return 0; |
