From patchwork Mon Mar 21 23:38:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 650631 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2LNeAOH021515 for ; Mon, 21 Mar 2011 23:40:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932429Ab1CUXjW (ORCPT ); Mon, 21 Mar 2011 19:39:22 -0400 Received: from ogre.sisk.pl ([217.79.144.158]:51891 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932238Ab1CUXjH (ORCPT ); Mon, 21 Mar 2011 19:39:07 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id 1FD021A5E7F; Tue, 22 Mar 2011 00:23:39 +0100 (CET) Received: from ogre.sisk.pl ([127.0.0.1]) by localhost (ogre.sisk.pl [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 22098-10; Tue, 22 Mar 2011 00:23:17 +0100 (CET) Received: from ferrari.rjw.lan (220-bem-13.acn.waw.pl [82.210.184.220]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ogre.sisk.pl (Postfix) with ESMTP id DDB9B1A5E8C; Tue, 22 Mar 2011 00:23:07 +0100 (CET) From: "Rafael J. Wysocki" To: Linux PM mailing list Subject: [PATCH 5/6] cpufreq: Use syscore_ops for boot CPU suspend/resume (v2) Date: Tue, 22 Mar 2011 00:38:01 +0100 User-Agent: KMail/1.13.6 (Linux/2.6.38+; KDE/4.6.0; x86_64; ; ) Cc: LKML , Greg KH , Kay Sievers , Jesse Barnes , "H. Peter Anvin" , mingo@redhat.com, tglx@linutronix.de, Dave Jones , Alan Stern , Avi Kivity , David Woodhouse , kvm@vger.kernel.org, iommu@lists.linux-foundation.org, cpufreq@vger.kernel.org References: <201103100131.58206.rjw@sisk.pl> <201103122212.40828.rjw@sisk.pl> <201103220031.22729.rjw@sisk.pl> In-Reply-To: <201103220031.22729.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201103220038.02116.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 21 Mar 2011 23:40:13 +0000 (UTC) Index: linux-2.6/drivers/cpufreq/cpufreq.c =================================================================== --- linux-2.6.orig/drivers/cpufreq/cpufreq.c +++ linux-2.6/drivers/cpufreq/cpufreq.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -1340,35 +1341,31 @@ out: } EXPORT_SYMBOL(cpufreq_get); +static struct sysdev_driver cpufreq_sysdev_driver = { + .add = cpufreq_add_dev, + .remove = cpufreq_remove_dev, +}; + /** - * cpufreq_suspend - let the low level driver prepare for suspend + * 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_suspend(struct sys_device *sysdev, pm_message_t pmsg) +static int cpufreq_bp_suspend(void) { int ret = 0; - int cpu = sysdev->id; + int cpu = smp_processor_id(); struct cpufreq_policy *cpu_policy; dprintk("suspending cpu %u\n", cpu); - if (!cpu_online(cpu)) - return 0; - - /* we may be lax here as interrupts are off. Nonetheless - * we need to grab the correct cpu policy, as to check - * whether we really run on this CPU. - */ - + /* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy = cpufreq_cpu_get(cpu); if (!cpu_policy) - return -EINVAL; - - /* only handle each CPU group once */ - if (unlikely(cpu_policy->cpu != cpu)) - goto out; + return 0; if (cpufreq_driver->suspend) { ret = cpufreq_driver->suspend(cpu_policy); @@ -1377,13 +1374,12 @@ static int cpufreq_suspend(struct sys_de "step on CPU %u\n", cpu_policy->cpu); } -out: cpufreq_cpu_put(cpu_policy); return ret; } /** - * cpufreq_resume - restore proper CPU frequency handling after resume + * 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 @@ -1391,31 +1387,23 @@ out: * 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 int cpufreq_resume(struct sys_device *sysdev) +static void cpufreq_bp_resume(void) { int ret = 0; - int cpu = sysdev->id; + int cpu = smp_processor_id(); struct cpufreq_policy *cpu_policy; dprintk("resuming cpu %u\n", cpu); - if (!cpu_online(cpu)) - return 0; - - /* we may be lax here as interrupts are off. Nonetheless - * we need to grab the correct cpu policy, as to check - * whether we really run on this CPU. - */ - + /* If there's no policy for the boot CPU, we have nothing to do. */ cpu_policy = cpufreq_cpu_get(cpu); if (!cpu_policy) - return -EINVAL; - - /* only handle each CPU group once */ - if (unlikely(cpu_policy->cpu != cpu)) - goto fail; + return; if (cpufreq_driver->resume) { ret = cpufreq_driver->resume(cpu_policy); @@ -1430,14 +1418,11 @@ static int cpufreq_resume(struct sys_dev fail: cpufreq_cpu_put(cpu_policy); - return ret; } -static struct sysdev_driver cpufreq_sysdev_driver = { - .add = cpufreq_add_dev, - .remove = cpufreq_remove_dev, - .suspend = cpufreq_suspend, - .resume = cpufreq_resume, +static struct syscore_ops cpufreq_syscore_ops = { + .suspend = cpufreq_bp_suspend, + .resume = cpufreq_bp_resume, }; @@ -2002,6 +1987,7 @@ static int __init cpufreq_core_init(void cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_sysdev_class.kset.kobj); BUG_ON(!cpufreq_global_kobject); + register_syscore_ops(&cpufreq_syscore_ops); return 0; }