Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: mxc: use a second rtc clock

The mxc RTC needs two clocks, one for the input
reference, and one for the IP. But this driver
was only using one clock (for the reference).
This patch add the second clock (for the IP).

Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Signed-off-by: Philippe Reynes <tremyfr@gmail.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>

authored by

Philippe Reynes and committed by
Shawn Guo
8f5fe778 def56bba

+28 -13
+28 -13
drivers/rtc/rtc-mxc.c
··· 79 79 struct rtc_device *rtc; 80 80 void __iomem *ioaddr; 81 81 int irq; 82 - struct clk *clk; 82 + struct clk *clk_ref; 83 + struct clk *clk_ipg; 83 84 struct rtc_time g_rtc_alarm; 84 85 enum imx_rtc_type devtype; 85 86 }; ··· 374 373 if (IS_ERR(pdata->ioaddr)) 375 374 return PTR_ERR(pdata->ioaddr); 376 375 377 - pdata->clk = devm_clk_get(&pdev->dev, NULL); 378 - if (IS_ERR(pdata->clk)) { 379 - dev_err(&pdev->dev, "unable to get clock!\n"); 380 - return PTR_ERR(pdata->clk); 376 + pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); 377 + if (IS_ERR(pdata->clk_ipg)) { 378 + dev_err(&pdev->dev, "unable to get ipg clock!\n"); 379 + return PTR_ERR(pdata->clk_ipg); 381 380 } 382 381 383 - ret = clk_prepare_enable(pdata->clk); 382 + ret = clk_prepare_enable(pdata->clk_ipg); 384 383 if (ret) 385 384 return ret; 386 385 387 - rate = clk_get_rate(pdata->clk); 386 + pdata->clk_ref = devm_clk_get(&pdev->dev, "ref"); 387 + if (IS_ERR(pdata->clk_ref)) { 388 + dev_err(&pdev->dev, "unable to get ref clock!\n"); 389 + ret = PTR_ERR(pdata->clk_ref); 390 + goto exit_put_clk_ipg; 391 + } 392 + 393 + ret = clk_prepare_enable(pdata->clk_ref); 394 + if (ret) 395 + goto exit_put_clk_ipg; 396 + 397 + rate = clk_get_rate(pdata->clk_ref); 388 398 389 399 if (rate == 32768) 390 400 reg = RTC_INPUT_CLK_32768HZ; ··· 406 394 else { 407 395 dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); 408 396 ret = -EINVAL; 409 - goto exit_put_clk; 397 + goto exit_put_clk_ref; 410 398 } 411 399 412 400 reg |= RTC_ENABLE_BIT; ··· 414 402 if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { 415 403 dev_err(&pdev->dev, "hardware module can't be enabled!\n"); 416 404 ret = -EIO; 417 - goto exit_put_clk; 405 + goto exit_put_clk_ref; 418 406 } 419 407 420 408 platform_set_drvdata(pdev, pdata); ··· 436 424 THIS_MODULE); 437 425 if (IS_ERR(rtc)) { 438 426 ret = PTR_ERR(rtc); 439 - goto exit_put_clk; 427 + goto exit_put_clk_ref; 440 428 } 441 429 442 430 pdata->rtc = rtc; 443 431 444 432 return 0; 445 433 446 - exit_put_clk: 447 - clk_disable_unprepare(pdata->clk); 434 + exit_put_clk_ref: 435 + clk_disable_unprepare(pdata->clk_ref); 436 + exit_put_clk_ipg: 437 + clk_disable_unprepare(pdata->clk_ipg); 448 438 449 439 return ret; 450 440 } ··· 455 441 { 456 442 struct rtc_plat_data *pdata = platform_get_drvdata(pdev); 457 443 458 - clk_disable_unprepare(pdata->clk); 444 + clk_disable_unprepare(pdata->clk_ref); 445 + clk_disable_unprepare(pdata->clk_ipg); 459 446 460 447 return 0; 461 448 }