diff options
| author | Pi-Cheng Chen <pi-cheng.chen@linaro.org> | 2015-12-09 22:48:13 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2015-12-11 20:27:16 -0500 |
| commit | 89b56047f6f9b15fa3e9df3e34fa391835972ab7 (patch) | |
| tree | 6bb8490762da6fd7905d586aebb4cad80a2988d1 /drivers/cpufreq | |
| parent | 63d1d656a5232f2f189b217b50542eadcf9d74ae (diff) | |
cpufreq: mt8173: Move resources allocation into ->probe()
Since the return value of ->init() of cpufreq driver is not propagated
to the device driver model now, move resources allocation into
->probe() to handle -EPROBE_DEFER properly.
Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq')
| -rw-r--r-- | drivers/cpufreq/mt8173-cpufreq.c | 92 |
1 files changed, 68 insertions, 24 deletions
diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c index 9d0fe37b4c3e..fd601b92f5ec 100644 --- a/drivers/cpufreq/mt8173-cpufreq.c +++ b/drivers/cpufreq/mt8173-cpufreq.c | |||
| @@ -41,16 +41,35 @@ | |||
| 41 | * the original PLL becomes stable at target frequency. | 41 | * the original PLL becomes stable at target frequency. |
| 42 | */ | 42 | */ |
| 43 | struct mtk_cpu_dvfs_info { | 43 | struct mtk_cpu_dvfs_info { |
| 44 | struct cpumask cpus; | ||
| 44 | struct device *cpu_dev; | 45 | struct device *cpu_dev; |
| 45 | struct regulator *proc_reg; | 46 | struct regulator *proc_reg; |
| 46 | struct regulator *sram_reg; | 47 | struct regulator *sram_reg; |
| 47 | struct clk *cpu_clk; | 48 | struct clk *cpu_clk; |
| 48 | struct clk *inter_clk; | 49 | struct clk *inter_clk; |
| 49 | struct thermal_cooling_device *cdev; | 50 | struct thermal_cooling_device *cdev; |
| 51 | struct list_head list_head; | ||
| 50 | int intermediate_voltage; | 52 | int intermediate_voltage; |
| 51 | bool need_voltage_tracking; | 53 | bool need_voltage_tracking; |
| 52 | }; | 54 | }; |
| 53 | 55 | ||
| 56 | static LIST_HEAD(dvfs_info_list); | ||
| 57 | |||
| 58 | static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(int cpu) | ||
| 59 | { | ||
| 60 | struct mtk_cpu_dvfs_info *info; | ||
| 61 | struct list_head *list; | ||
| 62 | |||
| 63 | list_for_each(list, &dvfs_info_list) { | ||
| 64 | info = list_entry(list, struct mtk_cpu_dvfs_info, list_head); | ||
| 65 | |||
| 66 | if (cpumask_test_cpu(cpu, &info->cpus)) | ||
| 67 | return info; | ||
| 68 | } | ||
| 69 | |||
| 70 | return NULL; | ||
| 71 | } | ||
| 72 | |||
| 54 | static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, | 73 | static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, |
| 55 | int new_vproc) | 74 | int new_vproc) |
| 56 | { | 75 | { |
| @@ -402,6 +421,9 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) | |||
| 402 | */ | 421 | */ |
| 403 | info->need_voltage_tracking = !IS_ERR(sram_reg); | 422 | info->need_voltage_tracking = !IS_ERR(sram_reg); |
| 404 | 423 | ||
| 424 | /* CPUs in the same cluster share a clock and power domain. */ | ||
| 425 | cpumask_copy(&info->cpus, &cpu_topology[cpu].core_sibling); | ||
| 426 | |||
| 405 | return 0; | 427 | return 0; |
| 406 | 428 | ||
| 407 | out_free_opp_table: | 429 | out_free_opp_table: |
| @@ -440,22 +462,18 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) | |||
| 440 | struct cpufreq_frequency_table *freq_table; | 462 | struct cpufreq_frequency_table *freq_table; |
| 441 | int ret; | 463 | int ret; |
| 442 | 464 | ||
| 443 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 465 | info = mtk_cpu_dvfs_info_lookup(policy->cpu); |
| 444 | if (!info) | 466 | if (!info) { |
| 445 | return -ENOMEM; | 467 | pr_err("dvfs info for cpu%d is not initialized.\n", |
| 446 | 468 | policy->cpu); | |
| 447 | ret = mtk_cpu_dvfs_info_init(info, policy->cpu); | 469 | return -EINVAL; |
| 448 | if (ret) { | ||
| 449 | pr_err("%s failed to initialize dvfs info for cpu%d\n", | ||
| 450 | __func__, policy->cpu); | ||
| 451 | goto out_free_dvfs_info; | ||
| 452 | } | 470 | } |
| 453 | 471 | ||
| 454 | ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); | 472 | ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); |
| 455 | if (ret) { | 473 | if (ret) { |
| 456 | pr_err("failed to init cpufreq table for cpu%d: %d\n", | 474 | pr_err("failed to init cpufreq table for cpu%d: %d\n", |
| 457 | policy->cpu, ret); | 475 | policy->cpu, ret); |
| 458 | goto out_release_dvfs_info; | 476 | return ret; |
| 459 | } | 477 | } |
| 460 | 478 | ||
| 461 | ret = cpufreq_table_validate_and_show(policy, freq_table); | 479 | ret = cpufreq_table_validate_and_show(policy, freq_table); |
| @@ -464,8 +482,7 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) | |||
| 464 | goto out_free_cpufreq_table; | 482 | goto out_free_cpufreq_table; |
| 465 | } | 483 | } |
| 466 | 484 | ||
| 467 | /* CPUs in the same cluster share a clock and power domain. */ | 485 | cpumask_copy(policy->cpus, &info->cpus); |
| 468 | cpumask_copy(policy->cpus, &cpu_topology[policy->cpu].core_sibling); | ||
| 469 | policy->driver_data = info; | 486 | policy->driver_data = info; |
| 470 | policy->clk = info->cpu_clk; | 487 | policy->clk = info->cpu_clk; |
| 471 | 488 | ||
| @@ -473,13 +490,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) | |||
| 473 | 490 | ||
| 474 | out_free_cpufreq_table: | 491 | out_free_cpufreq_table: |
| 475 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); | 492 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); |
| 476 | |||
| 477 | out_release_dvfs_info: | ||
| 478 | mtk_cpu_dvfs_info_release(info); | ||
| 479 | |||
| 480 | out_free_dvfs_info: | ||
| 481 | kfree(info); | ||
| 482 | |||
| 483 | return ret; | 493 | return ret; |
| 484 | } | 494 | } |
| 485 | 495 | ||
| @@ -489,8 +499,6 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy) | |||
| 489 | 499 | ||
| 490 | cpufreq_cooling_unregister(info->cdev); | 500 | cpufreq_cooling_unregister(info->cdev); |
| 491 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); | 501 | dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); |
| 492 | mtk_cpu_dvfs_info_release(info); | ||
| 493 | kfree(info); | ||
| 494 | 502 | ||
| 495 | return 0; | 503 | return 0; |
| 496 | } | 504 | } |
| @@ -510,11 +518,47 @@ static struct cpufreq_driver mt8173_cpufreq_driver = { | |||
| 510 | 518 | ||
| 511 | static int mt8173_cpufreq_probe(struct platform_device *pdev) | 519 | static int mt8173_cpufreq_probe(struct platform_device *pdev) |
| 512 | { | 520 | { |
| 513 | int ret; | 521 | struct mtk_cpu_dvfs_info *info; |
| 522 | struct list_head *list, *tmp; | ||
| 523 | int cpu, ret; | ||
| 524 | |||
| 525 | for_each_possible_cpu(cpu) { | ||
| 526 | info = mtk_cpu_dvfs_info_lookup(cpu); | ||
| 527 | if (info) | ||
| 528 | continue; | ||
| 529 | |||
| 530 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||
| 531 | if (!info) { | ||
| 532 | ret = -ENOMEM; | ||
| 533 | goto release_dvfs_info_list; | ||
| 534 | } | ||
| 535 | |||
| 536 | ret = mtk_cpu_dvfs_info_init(info, cpu); | ||
| 537 | if (ret) { | ||
| 538 | dev_err(&pdev->dev, | ||
| 539 | "failed to initialize dvfs info for cpu%d\n", | ||
| 540 | cpu); | ||
| 541 | goto release_dvfs_info_list; | ||
| 542 | } | ||
| 543 | |||
| 544 | list_add(&info->list_head, &dvfs_info_list); | ||
| 545 | } | ||
| 514 | 546 | ||
| 515 | ret = cpufreq_register_driver(&mt8173_cpufreq_driver); | 547 | ret = cpufreq_register_driver(&mt8173_cpufreq_driver); |
| 516 | if (ret) | 548 | if (ret) { |
| 517 | pr_err("failed to register mtk cpufreq driver\n"); | 549 | dev_err(&pdev->dev, "failed to register mtk cpufreq driver\n"); |
| 550 | goto release_dvfs_info_list; | ||
| 551 | } | ||
| 552 | |||
| 553 | return 0; | ||
| 554 | |||
| 555 | release_dvfs_info_list: | ||
| 556 | list_for_each_safe(list, tmp, &dvfs_info_list) { | ||
| 557 | info = list_entry(list, struct mtk_cpu_dvfs_info, list_head); | ||
| 558 | |||
| 559 | mtk_cpu_dvfs_info_release(info); | ||
| 560 | list_del(list); | ||
| 561 | } | ||
| 518 | 562 | ||
| 519 | return ret; | 563 | return ret; |
| 520 | } | 564 | } |
