From patchwork Thu Dec 10 03:48:13 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: 7814511 Return-Path: X-Original-To: patchwork-linux-mediatek@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D32229F387 for ; Thu, 10 Dec 2015 03:48:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D191C2052C for ; Thu, 10 Dec 2015 03:48:48 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E6BC8204C9 for ; Thu, 10 Dec 2015 03:48:47 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a6sDn-00046h-It; Thu, 10 Dec 2015 03:48:47 +0000 Received: from mail-pf0-x234.google.com ([2607:f8b0:400e:c00::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a6sDk-00044B-PK for linux-mediatek@lists.infradead.org; Thu, 10 Dec 2015 03:48:45 +0000 Received: by pfu207 with SMTP id 207so40688709pfu.2 for ; Wed, 09 Dec 2015 19:48:23 -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=37c3FdtMOPyIyoH8/wVhkrk+0nj3wT5IYViZIAoTTEU=; b=C98RAMpYzQy+tJxpaO7v94uZKNoCZJUZfrGHNJ9DDWQzj34ijX25oEmeNsaYWQQ46Q tESCGjNAm0/UbWO/fgM35wEBEwLeiubSSNcEbLQtGu6qV9wWydA3SYDVtLCpnglWEqzp GhY7Nlgo/yqP/RWr8p3+gUpou4HJbAm6b8bsSA8VE+u6EMoV24QWGTSI6dQ4OiwBBqE1 DytnsCYGL6ScQYF4G3QDRGYtkr1Pdotv2ZOdyP8XauOH1X2hhn47Icf1UV1l0iTpRalr nphp5WoPvhyC37JpbEJLfGEqjOhl0K9Cyu3Q1hVvrewwCwaIE542mfjZH3tDyGl22ce0 Dppw== 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=37c3FdtMOPyIyoH8/wVhkrk+0nj3wT5IYViZIAoTTEU=; b=Iam+wfwa7mlmavz/xMXoHzqmDlouFm/47xzriODYmCYTo+bndSk5kTxa0ZjJ3RtTH7 o7rxKkC8b+X/SYVnkrj3u7Ilb4IeMT8hMY1TyCdRK4iCclFpKwCtj4NzzTqcEq5g8eZc RmIB5L0ITiTdYK+tJKyGPqceShjdwWwfnINoyxiupF/FPtbm1n28uJ+QVi7N5RjIvaSx EY/oIMZaXg+NoWq0ZTgSx1MO4+glIdix6cNqaBrTFES7DPuqmOXOQN/k+ZYx5GadxZwF AIQVhkbgU486bL2nPnqG7N6OzVBBXtxBniOJ6mQaHxtLZSUU6x2oobsHRlykC7rTaURh 9F6Q== X-Gm-Message-State: ALoCoQl6FAwL2QR6jGqASDw/qV2MiuBar0VlUgQt6WCsuMg7UL4xIdrBl3kdnPCqQkr18Vb7HDflAYKommJy8ZUXOgkaTjFGSw== X-Received: by 10.98.64.209 with SMTP id f78mr3543828pfd.74.1449719303687; Wed, 09 Dec 2015 19:48:23 -0800 (PST) Received: from localhost.localdomain ([124.219.30.17]) by smtp.googlemail.com with ESMTPSA id 25sm14721281pfp.62.2015.12.09.19.48.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Dec 2015 19:48:23 -0800 (PST) From: Pi-Cheng Chen To: "Rafael J. Wysocki" , Viresh Kumar , Matthias Brugger Subject: [PATCH v3] cpufreq: mt8173: move resources allocation into ->probe() Date: Thu, 10 Dec 2015 11:48:13 +0800 Message-Id: <1449719293-7966-1-git-send-email-pi-cheng.chen@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <3188378.Wlzx7Ukr89@vostro.rjw.lan> References: <3188378.Wlzx7Ukr89@vostro.rjw.lan> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151209_194844_944199_53AF6B17 X-CRM114-Status: GOOD ( 16.38 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, Ricky Liang , linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Acked-by: Viresh Kumar --- v2->v3: - rename get_dvfs_info() as mtk_cpu_dvfs_info_lookup() - fix some minor issues of v2 v1->v2: - fix error handling path in ->probe() --- drivers/cpufreq/mt8173-cpufreq.c | 92 +++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c index 9d0fe37..fd601b9 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); + +static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_lookup(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,22 +462,18 @@ 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 = mtk_cpu_dvfs_info_lookup(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); @@ -464,8 +482,7 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) goto out_free_cpufreq_table; } - /* 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; @@ -473,13 +490,6 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) 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; } @@ -489,8 +499,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 +518,47 @@ 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 = mtk_cpu_dvfs_info_lookup(cpu); + if (info) + continue; + + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) { + ret = -ENOMEM; + goto release_dvfs_info_list; + } + + ret = mtk_cpu_dvfs_info_init(info, cpu); + if (ret) { + dev_err(&pdev->dev, + "failed to initialize dvfs info for cpu%d\n", + cpu); + goto release_dvfs_info_list; + } + + list_add(&info->list_head, &dvfs_info_list); + } ret = cpufreq_register_driver(&mt8173_cpufreq_driver); - if (ret) - pr_err("failed to register mtk cpufreq driver\n"); + if (ret) { + dev_err(&pdev->dev, "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); + } return ret; }