From patchwork Sat Dec 5 06:01:46 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pi-cheng.chen" X-Patchwork-Id: 57737 Delivered-To: patch@linaro.org Received: by 10.112.147.194 with SMTP id tm2csp19253lbb; Fri, 4 Dec 2015 22:02:00 -0800 (PST) X-Received: by 10.98.0.140 with SMTP id 134mr27227458pfa.6.1449295320529; Fri, 04 Dec 2015 22:02:00 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e85si24452194pfb.97.2015.12.04.22.02.00; Fri, 04 Dec 2015 22:02:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-pm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-pm-owner@vger.kernel.org; dkim=neutral (body hash did not verify) header.i=@linaro-org.20150623.gappssmtp.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751172AbbLEGB4 (ORCPT + 11 others); Sat, 5 Dec 2015 01:01:56 -0500 Received: from mail-pa0-f43.google.com ([209.85.220.43]:34250 "EHLO mail-pa0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750982AbbLEGBz (ORCPT ); Sat, 5 Dec 2015 01:01:55 -0500 Received: by pacwq6 with SMTP id wq6so19927201pac.1 for ; Fri, 04 Dec 2015 22:01:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro-org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mPMlWCWDPa2dlC8TqVKnO0T5QsVPBtjxWihJ9j4yhrU=; b=K5X8jZq4hZ/65VxrLwVgcCcjk7Rm8wYhIWYIZxemd8ZHkDPzeuq1IdEQ0M6AihDRYJ x9TTuTHL2RorDPESMY8KutmWhSKpqcGfw9p0g6NwPDYH01kOz0pOUec4afsnk0GJAByK ZDxT0EgAXhpqaskfcsDWJK3aKfPWeggFkz/KJzu0vAWPY2577u0ertCeyh4+OVDorgIV 27FuGbSuZdqV5YyatDo5RrL3/aHgqR+84cpzgsxnzDZGCdNhr+pBr4dFj5iDL18Nh9Ek mkIUWrpCy+uN5GvDAxt/fjbFunTuHVXsATnTORpSCjy8/pa7k5wgaSX7ee/afcxBhiSQ Qpxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=mPMlWCWDPa2dlC8TqVKnO0T5QsVPBtjxWihJ9j4yhrU=; b=VRACVuary1Z5RpsF+4K5x0wSEHsfS2MnitEMEW3J4WJPJfxyDFMnc++AUsRZd5IscO EWyuZGhkeSl4J3oZOpTfXAE6lG8ETbG7aIZ7KP7YMNnnqMMX7NQANWPBUXVmhfce1bIn aAAfC9IDHvzzFvOnYRwhwOpWTKsDB7Wiw5OAwBbPfJZ60mtR371et+TAdlA/B9f5KNg0 S/ORLOti0LnRQSTFyjsJNJNQTW52MX6fE2bX0eWxOacOwYp3F/44qgBIxJt+seNH2Lpw 7mTDxF5gX3zkZvCbZEnBh5HQdDWjct22gBT9n2zUwCMxCmdp9EbO7/QQMfSO7DlyrCSp Vzgw== X-Gm-Message-State: ALoCoQnWoInzbFA1EYdI6fyQyXxzuMb1zNyztvhS82UWoccqEu+f/XE7WRyYilHifuqkc3jdvZdr X-Received: by 10.66.146.130 with SMTP id tc2mr26606228pab.26.1449295315351; Fri, 04 Dec 2015 22:01:55 -0800 (PST) Received: from localhost.localdomain ([124.219.30.17]) by smtp.googlemail.com with ESMTPSA id w8sm20637363pfi.41.2015.12.04.22.01.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 04 Dec 2015 22:01:54 -0800 (PST) From: Pi-Cheng Chen To: Viresh Kumar , Matthias Brugger Cc: Daniel Kurtz , Ricky Liang , linux-mediatek@lists.infradead.org, linaro-kernel@lists.linaro.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org Subject: [PATCH v2] cpufreq: mt8173: move resources allocation into ->probe() Date: Sat, 5 Dec 2015 14:01:46 +0800 Message-Id: <1449295306-9222-1-git-send-email-pi-cheng.chen@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1448785898-17838-4-git-send-email-pi-cheng.chen@linaro.org> References: <1448785898-17838-4-git-send-email-pi-cheng.chen@linaro.org> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 --- v1->v2: - fix error handling path in ->probe() --- drivers/cpufreq/mt8173-cpufreq.c | 98 ++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 28 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Acked-by: Viresh Kumar diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c index 9d0fe37..257bcb9 100644 --- a/drivers/cpufreq/mt8173-cpufreq.c +++ b/drivers/cpufreq/mt8173-cpufreq.c @@ -41,16 +41,35 @@ * the original PLL becomes stable at target frequency. */ struct mtk_cpu_dvfs_info { + struct cpumask cpus; struct device *cpu_dev; struct regulator *proc_reg; struct regulator *sram_reg; struct clk *cpu_clk; struct clk *inter_clk; struct thermal_cooling_device *cdev; + struct list_head list_head; int intermediate_voltage; bool need_voltage_tracking; }; +static LIST_HEAD(dvfs_info_list); + +struct mtk_cpu_dvfs_info *get_dvfs_info(int cpu) +{ + struct mtk_cpu_dvfs_info *info; + struct list_head *list; + + list_for_each(list, &dvfs_info_list) { + info = list_entry(list, struct mtk_cpu_dvfs_info, list_head); + + if (cpumask_test_cpu(cpu, &info->cpus)) + return info; + } + + return NULL; +} + static int mtk_cpufreq_voltage_tracking(struct mtk_cpu_dvfs_info *info, int new_vproc) { @@ -402,6 +421,9 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) */ info->need_voltage_tracking = !IS_ERR(sram_reg); + /* CPUs in the same cluster share a clock and power domain. */ + cpumask_copy(&info->cpus, &cpu_topology[cpu].core_sibling); + return 0; out_free_opp_table: @@ -440,47 +462,32 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) struct cpufreq_frequency_table *freq_table; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - ret = mtk_cpu_dvfs_info_init(info, policy->cpu); - if (ret) { - pr_err("%s failed to initialize dvfs info for cpu%d\n", - __func__, policy->cpu); - goto out_free_dvfs_info; + info = get_dvfs_info(policy->cpu); + if (!info) { + pr_err("dvfs info for cpu%d is not initialized.\n", + policy->cpu); + return -EINVAL; } ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table); if (ret) { pr_err("failed to init cpufreq table for cpu%d: %d\n", policy->cpu, ret); - goto out_release_dvfs_info; + return ret; } ret = cpufreq_table_validate_and_show(policy, freq_table); if (ret) { pr_err("%s: invalid frequency table: %d\n", __func__, ret); - goto out_free_cpufreq_table; + dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); + return ret; } - /* CPUs in the same cluster share a clock and power domain. */ - cpumask_copy(policy->cpus, &cpu_topology[policy->cpu].core_sibling); + cpumask_copy(policy->cpus, &info->cpus); policy->driver_data = info; policy->clk = info->cpu_clk; return 0; - -out_free_cpufreq_table: - dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); - -out_release_dvfs_info: - mtk_cpu_dvfs_info_release(info); - -out_free_dvfs_info: - kfree(info); - - return ret; } static int mtk_cpufreq_exit(struct cpufreq_policy *policy) @@ -489,8 +496,6 @@ static int mtk_cpufreq_exit(struct cpufreq_policy *policy) cpufreq_cooling_unregister(info->cdev); dev_pm_opp_free_cpufreq_table(info->cpu_dev, &policy->freq_table); - mtk_cpu_dvfs_info_release(info); - kfree(info); return 0; } @@ -510,11 +515,48 @@ static struct cpufreq_driver mt8173_cpufreq_driver = { static int mt8173_cpufreq_probe(struct platform_device *pdev) { - int ret; + struct mtk_cpu_dvfs_info *info; + struct list_head *list, *tmp; + int cpu, ret; + + for_each_possible_cpu(cpu) { + info = get_dvfs_info(cpu); + if (info) + continue; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + ret = -ENOMEM; + goto release_dvfs_info_list; + } + + ret = mtk_cpu_dvfs_info_init(info, cpu); + if (ret) { + pr_err("%s failed to initialize dvfs info for cpu%d\n", + __func__, cpu); + kfree(info); + goto release_dvfs_info_list; + } + + list_add(&info->list_head, &dvfs_info_list); + } ret = cpufreq_register_driver(&mt8173_cpufreq_driver); - if (ret) + if (ret) { pr_err("failed to register mtk cpufreq driver\n"); + goto release_dvfs_info_list; + } + + return 0; + +release_dvfs_info_list: + list_for_each_safe(list, tmp, &dvfs_info_list) { + info = list_entry(list, struct mtk_cpu_dvfs_info, list_head); + + mtk_cpu_dvfs_info_release(info); + list_del(list); + kfree(info); + } return ret; }