From patchwork Thu Feb 13 06:50:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 24569 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f200.google.com (mail-vc0-f200.google.com [209.85.220.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 98AC7202E2 for ; Thu, 13 Feb 2014 06:53:16 +0000 (UTC) Received: by mail-vc0-f200.google.com with SMTP id le5sf21777806vcb.3 for ; Wed, 12 Feb 2014 22:53:15 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:in-reply-to:references :sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=NflO8VOZ3XaoHdopc6ovg52f9KUcyqmgkPKJwId7W4I=; b=lIS03hrFv/opXqf5dT3/TiVb/j/0V4OkMKy1Wa12H+xaF4JaKy7TDt31pf1QayH8t5 WPHQDX+jNqCnrpcVyif5ybtxivG7IOLVPdFuVWCgI4q08cugXI7eDakDkoJmhPLaJtde k+TfOtUM8NJl0DIsmyN7klYVlRkvOqpHjK9Zic4S7hCLtElhOKdYlc+pwee++ZgBjRRb OBioeIFOVTDCkJgICxTnYCjoJpb+AniaqddqobJVZoejl/xzgArQkrbXFGRB+zxB22yD 0/yS7rsKdlYLRmbHO/vA2e9DJgRMCriZXlqT2WGRuKTB1QIlR6ElDPuJcgLZMFn0YQje JFdw== X-Gm-Message-State: ALoCoQk9bW2LoSYtcgQUhlanqV5P+0Dmj8ctA7SPjaDUxdKsNgbraME9wqwOx2oTB5yyPKZqCID2 X-Received: by 10.58.85.3 with SMTP id d3mr3560669vez.40.1392274395794; Wed, 12 Feb 2014 22:53:15 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.27.117 with SMTP id 108ls3441556qgw.77.gmail; Wed, 12 Feb 2014 22:53:15 -0800 (PST) X-Received: by 10.52.107.35 with SMTP id gz3mr30258008vdb.8.1392274395678; Wed, 12 Feb 2014 22:53:15 -0800 (PST) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id zp2si356391vec.8.2014.02.12.22.53.15 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 12 Feb 2014 22:53:15 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id cz12so8256854veb.15 for ; Wed, 12 Feb 2014 22:53:15 -0800 (PST) X-Received: by 10.52.61.133 with SMTP id p5mr26552702vdr.4.1392274395558; Wed, 12 Feb 2014 22:53:15 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp3249vcz; Wed, 12 Feb 2014 22:53:15 -0800 (PST) X-Received: by 10.66.240.4 with SMTP id vw4mr44113275pac.26.1392274394648; Wed, 12 Feb 2014 22:53:14 -0800 (PST) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x3si981002pbk.23.2014.02.12.22.52.44; Wed, 12 Feb 2014 22:52:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753219AbaBMGvH (ORCPT + 27 others); Thu, 13 Feb 2014 01:51:07 -0500 Received: from mail-wi0-f169.google.com ([209.85.212.169]:61480 "EHLO mail-wi0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753175AbaBMGvB (ORCPT ); Thu, 13 Feb 2014 01:51:01 -0500 Received: by mail-wi0-f169.google.com with SMTP id e4so2815549wiv.2 for ; Wed, 12 Feb 2014 22:50:59 -0800 (PST) X-Received: by 10.180.25.46 with SMTP id z14mr1182676wif.49.1392274258933; Wed, 12 Feb 2014 22:50:58 -0800 (PST) Received: from localhost ([213.122.173.131]) by mx.google.com with ESMTPSA id fb8sm11575324wic.3.2014.02.12.22.50.54 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Wed, 12 Feb 2014 22:50:58 -0800 (PST) From: Viresh Kumar To: rjw@rjwysocki.net Cc: linaro-kernel@lists.linaro.org, cpufreq@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, nm@ti.com, swarren@wwwdotorg.org, kgene.kim@samsung.com, jinchoi@broadcom.com, tianyu.lan@intel.com, sebastian.capella@linaro.org, jhbird.choi@samsung.com, Viresh Kumar Subject: [PATCH V5 3/7] cpufreq: call driver's suspend/resume for each policy Date: Thu, 13 Feb 2014 12:20:18 +0530 Message-Id: X-Mailer: git-send-email 1.7.12.rc2.18.g61b472e In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: viresh.kumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Earlier cpufreq suspend/resume callbacks into drivers were getting called only for the boot CPU, as by the time callbacks were called non-boot CPUs were already removed. Because we might still need driver specific actions on suspend/resume, its better to use earlier infrastructure from the early suspend/late resume calls. In effect, we call suspend/resume for each policy. The resume part also takes care of synchronising frequency for boot CPU, which might turn out be different than what cpufreq core believes. Hence, the earlier syscore infrastructure is getting removed now. Tested-by: Lan Tianyu Tested-by: Nishanth Menon Tested-by: Stephen Warren Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq.c | 112 +++++++++++++--------------------------------- 1 file changed, 32 insertions(+), 80 deletions(-) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index cb23858..87a4b96 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -1580,6 +1579,14 @@ static struct subsys_interface cpufreq_interface = { .remove_dev = cpufreq_remove_dev, }; +/** + * cpufreq_suspend() - Suspend CPUFreq governors + * + * Called during system wide Suspend/Hibernate cycles for suspending governors + * as some platforms can't change frequency after this point in suspend cycle. + * Because some of the devices (like: i2c, regulators, etc) they use for + * changing frequency are suspended quickly after this point. + */ void cpufreq_suspend(void) { struct cpufreq_policy *policy; @@ -1589,14 +1596,25 @@ void cpufreq_suspend(void) pr_debug("%s: Suspending Governors\n", __func__); - list_for_each_entry(policy, &cpufreq_policy_list, policy_list) + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { if (__cpufreq_governor(policy, CPUFREQ_GOV_STOP)) pr_err("%s: Failed to stop governor for policy: %p\n", __func__, policy); + else if (cpufreq_driver->suspend + && cpufreq_driver->suspend(policy)) + pr_err("%s: Failed to suspend driver: %p\n", __func__, + policy); + } cpufreq_suspended = true; } +/** + * cpufreq_resume() - Resume CPUFreq governors + * + * Called during system wide Suspend/Hibernate cycle for resuming governors that + * are suspended with cpufreq_suspend(). + */ void cpufreq_resume(void) { struct cpufreq_policy *policy; @@ -1608,91 +1626,26 @@ void cpufreq_resume(void) cpufreq_suspended = false; - list_for_each_entry(policy, &cpufreq_policy_list, policy_list) + list_for_each_entry(policy, &cpufreq_policy_list, policy_list) { if (__cpufreq_governor(policy, CPUFREQ_GOV_START) || __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS)) pr_err("%s: Failed to start governor for policy: %p\n", __func__, policy); -} - -/** - * cpufreq_bp_suspend - Prepare the boot CPU for system suspend. - * - * This function is only executed for the boot processor. The other CPUs - * have been put offline by means of CPU hotplug. - */ -static int cpufreq_bp_suspend(void) -{ - int ret = 0; - - int cpu = smp_processor_id(); - struct cpufreq_policy *policy; - - pr_debug("suspending cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - policy = cpufreq_cpu_get(cpu); - if (!policy) - return 0; - - if (cpufreq_driver->suspend) { - ret = cpufreq_driver->suspend(policy); - if (ret) - printk(KERN_ERR "cpufreq: suspend failed in ->suspend " - "step on CPU %u\n", policy->cpu); - } - - cpufreq_cpu_put(policy); - return ret; -} - -/** - * cpufreq_bp_resume - Restore proper frequency handling of the boot CPU. - * - * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) - * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are - * restored. It will verify that the current freq is in sync with - * what we believe it to be. This is a bit later than when it - * should be, but nonethteless it's better than calling - * cpufreq_driver->get() here which might re-enable interrupts... - * - * This function is only executed for the boot CPU. The other CPUs have not - * been turned on yet. - */ -static void cpufreq_bp_resume(void) -{ - int ret = 0; + else if (cpufreq_driver->resume + && cpufreq_driver->resume(policy)) + pr_err("%s: Failed to resume driver: %p\n", __func__, + policy); - int cpu = smp_processor_id(); - struct cpufreq_policy *policy; - - pr_debug("resuming cpu %u\n", cpu); - - /* If there's no policy for the boot CPU, we have nothing to do. */ - policy = cpufreq_cpu_get(cpu); - if (!policy) - return; - - if (cpufreq_driver->resume) { - ret = cpufreq_driver->resume(policy); - if (ret) { - printk(KERN_ERR "cpufreq: resume failed in ->resume " - "step on CPU %u\n", policy->cpu); - goto fail; - } + /* + * schedule call cpufreq_update_policy() for boot CPU, i.e. last + * policy in list. It will verify that the current freq is in + * sync with what we believe it to be. + */ + if (list_is_last(&policy->policy_list, &cpufreq_policy_list)) + schedule_work(&policy->update); } - - schedule_work(&policy->update); - -fail: - cpufreq_cpu_put(policy); } -static struct syscore_ops cpufreq_syscore_ops = { - .suspend = cpufreq_bp_suspend, - .resume = cpufreq_bp_resume, -}; - /** * cpufreq_get_current_driver - return current driver's name * @@ -2458,7 +2411,6 @@ static int __init cpufreq_core_init(void) cpufreq_global_kobject = kobject_create(); BUG_ON(!cpufreq_global_kobject); - register_syscore_ops(&cpufreq_syscore_ops); return 0; }