From patchwork Tue Jun 7 16:30:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trinabh Gupta X-Patchwork-Id: 99295 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id 00FCAB7792 for ; Wed, 8 Jun 2011 02:35:06 +1000 (EST) Received: by ozlabs.org (Postfix) id F0D22B6FB8; Wed, 8 Jun 2011 02:30:33 +1000 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: from e28smtp02.in.ibm.com (e28smtp02.in.ibm.com [122.248.162.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e28smtp02.in.ibm.com", Issuer "GeoTrust SSL CA" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id 82180B6F8E for ; Wed, 8 Jun 2011 02:30:33 +1000 (EST) Received: from d28relay03.in.ibm.com (d28relay03.in.ibm.com [9.184.220.60]) by e28smtp02.in.ibm.com (8.14.4/8.13.1) with ESMTP id p57GUTbL016745 for ; Tue, 7 Jun 2011 22:00:29 +0530 Received: from d28av05.in.ibm.com (d28av05.in.ibm.com [9.184.220.67]) by d28relay03.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p57GUTBl4358228 for ; Tue, 7 Jun 2011 22:00:29 +0530 Received: from d28av05.in.ibm.com (loopback [127.0.0.1]) by d28av05.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p57GUS7I028717 for ; Wed, 8 Jun 2011 02:30:28 +1000 Received: from tringupt.in.ibm.com ([9.77.86.66]) by d28av05.in.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p57GUQsW028594; Wed, 8 Jun 2011 02:30:27 +1000 From: Trinabh Gupta Subject: [RFC PATCH V1 6/7] cpuidle: (POWER) Enable cpuidle and directly call cpuidle_idle_call() for pSeries To: linux-pm@lists.linux-foundation.org, linuxppc-dev@ozlabs.org Date: Tue, 07 Jun 2011 22:00:26 +0530 Message-ID: <20110607163024.6848.22009.stgit@tringupt.in.ibm.com> In-Reply-To: <20110607162847.6848.44707.stgit@tringupt.in.ibm.com> References: <20110607162847.6848.44707.stgit@tringupt.in.ibm.com> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 08 Jun 2011 02:34:05 +1000 Cc: linux-kernel@vger.kernel.org X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org This patch enables cpuidle for pSeries and cpuidle_idle_call() is directly called from the idle loop. As a result pseries_idle cpuidle driver registered with cpuidle subsystem comes into action. This patch also removes the routines pseries_shared_idle_sleep and pseries_dedicated_idle_sleep as they are now implemented as part of pseries_idle cpuidle driver. Signed-off-by: Trinabh Gupta Signed-off-by: Arun R Bharadwaj --- arch/powerpc/platforms/Kconfig | 6 ++ arch/powerpc/platforms/pseries/Kconfig | 2 - arch/powerpc/platforms/pseries/setup.c | 86 +------------------------------- include/linux/cpuidle.h | 2 - 4 files changed, 9 insertions(+), 87 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index f970ca2..80e3592 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -206,6 +206,12 @@ config PPC_PASEMI_CPUFREQ endmenu +menu "CPUIdle driver" + +source "drivers/cpuidle/Kconfig" + +endmenu + config PPC601_SYNC_FIX bool "Workarounds for PPC601 bugs" depends on 6xx && (PPC_PREP || PPC_PMAC) diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 877bac6..9729086 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -121,7 +121,7 @@ config DTL config PSERIES_IDLE tristate "Cpuidle driver for pSeries platforms" - depends on CPU_IDLE + select CPU_IDLE depends on PPC_PSERIES default y help diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 6893a0c..75d024b 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -74,9 +75,6 @@ EXPORT_SYMBOL(CMO_PageSize); int fwnmi_active; /* TRUE if an FWNMI handler is present */ -static void pseries_shared_idle_sleep(void); -static void pseries_dedicated_idle_sleep(void); - static struct device_node *pSeries_mpic_node; static void pSeries_show_cpuinfo(struct seq_file *m) @@ -373,18 +371,9 @@ static void __init pSeries_setup_arch(void) pSeries_nvram_init(); - /* Choose an idle loop */ if (firmware_has_feature(FW_FEATURE_SPLPAR)) { vpa_init(boot_cpuid); - if (get_lppaca()->shared_proc) { - printk(KERN_DEBUG "Using shared processor idle loop\n"); - ppc_md.power_save = pseries_shared_idle_sleep; - } else { - printk(KERN_DEBUG "Using dedicated idle loop\n"); - ppc_md.power_save = pseries_dedicated_idle_sleep; - } - } else { - printk(KERN_DEBUG "Using default idle loop\n"); + ppc_md.power_save = (void *)cpuidle_idle_call; } if (firmware_has_feature(FW_FEATURE_LPAR)) @@ -584,77 +573,6 @@ static int __init pSeries_probe(void) return 1; } -static void pseries_dedicated_idle_sleep(void) -{ - unsigned int cpu = smp_processor_id(); - unsigned long start_snooze; - unsigned long in_purr, out_purr; - long snooze = __get_cpu_var(smt_snooze_delay); - - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; - get_lppaca()->donate_dedicated_cpu = 1; - in_purr = mfspr(SPRN_PURR); - - /* - * We come in with interrupts disabled, and need_resched() - * has been checked recently. If we should poll for a little - * while, do so. - */ - if (snooze) { - start_snooze = get_tb() + snooze * tb_ticks_per_usec; - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); - - while ((snooze < 0) || (get_tb() < start_snooze)) { - if (need_resched() || cpu_is_offline(cpu)) - goto out; - ppc64_runlatch_off(); - HMT_low(); - HMT_very_low(); - } - - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); - smp_mb(); - local_irq_disable(); - if (need_resched() || cpu_is_offline(cpu)) - goto out; - } - - cede_processor(); - -out: - HMT_medium(); - out_purr = mfspr(SPRN_PURR); - get_lppaca()->wait_state_cycles += out_purr - in_purr; - get_lppaca()->donate_dedicated_cpu = 0; - get_lppaca()->idle = 0; -} - -static void pseries_shared_idle_sleep(void) -{ - /* - * Indicate to the HV that we are idle. Now would be - * a good time to find other work to dispatch. - */ - get_lppaca()->idle = 1; - - /* - * Yield the processor to the hypervisor. We return if - * an external interrupt occurs (which are driven prior - * to returning here) or if a prod occurs from another - * processor. When returning here, external interrupts - * are enabled. - */ - cede_processor(); - - get_lppaca()->idle = 0; -} - static int pSeries_pci_probe_mode(struct pci_bus *bus) { if (firmware_has_feature(FW_FEATURE_LPAR)) diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index c904188..701bc9b 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -129,7 +129,6 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern void disable_cpuidle(void); extern int cpuidle_idle_call(void); - extern int cpuidle_register_driver(struct cpuidle_driver *drv); struct cpuidle_driver *cpuidle_get_driver(void); extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); @@ -144,7 +143,6 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev); #else static inline void disable_cpuidle(void) { } static inline int cpuidle_idle_call(void) { return -ENODEV; } - static inline int cpuidle_register_driver(struct cpuidle_driver *drv) {return -ENODEV; } static inline struct cpuidle_driver *cpuidle_get_driver(void) {return NULL; }