From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from e28smtp07.in.ibm.com (e28smtp07.in.ibm.com [59.145.155.7]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e28smtp07.in.ibm.com", Issuer "Equifax" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 99468B7BA8 for ; Tue, 1 Sep 2009 21:39:58 +1000 (EST) Received: from d28relay05.in.ibm.com (d28relay05.in.ibm.com [9.184.220.62]) by e28smtp07.in.ibm.com (8.14.3/8.13.1) with ESMTP id n81Bdi4T002161 for ; Tue, 1 Sep 2009 17:09:44 +0530 Received: from d28av04.in.ibm.com (d28av04.in.ibm.com [9.184.220.66]) by d28relay05.in.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id n81Bdiia2449648 for ; Tue, 1 Sep 2009 17:09:44 +0530 Received: from d28av04.in.ibm.com (loopback [127.0.0.1]) by d28av04.in.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id n81Bdhwx009455 for ; Tue, 1 Sep 2009 21:39:43 +1000 Date: Tue, 1 Sep 2009 17:09:41 +0530 From: Arun R Bharadwaj To: Joel Schopp , Benjamin Herrenschmidt , Paul Mackerras , Peter Zijlstra , Ingo Molnar , Vaidyanathan Srinivasan , Dipankar Sarma , Balbir Singh , Gautham R Shenoy , Arun Bharadwaj Subject: [v4 PATCH 2/5]: cpuidle: Implement routines to register and unregister idle function. Message-ID: <20090901113941.GI7599@linux.vnet.ibm.com> References: <20090901113704.GG7599@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 In-Reply-To: <20090901113704.GG7599@linux.vnet.ibm.com> Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Reply-To: arun@linux.vnet.ibm.com List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , * Arun R Bharadwaj [2009-09-01 17:07:04]: Implement a LIFO based approach for registering arch dependent idle routines. This is a prototype for pseries, needs to be extended for other platforms. Signed-off-by: Arun R Bharadwaj --- arch/powerpc/kernel/idle.c | 5 +++++ drivers/cpuidle/cpuidle.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/pm.h | 10 ++++++++++ 3 files changed, 52 insertions(+) Index: linux.trees.git/arch/powerpc/kernel/idle.c =================================================================== --- linux.trees.git.orig/arch/powerpc/kernel/idle.c +++ linux.trees.git/arch/powerpc/kernel/idle.c @@ -46,6 +46,11 @@ static int __init powersave_off(char *ar } __setup("powersave=off", powersave_off); +void set_arch_idle(void (*idle)(void)) +{ + ppc_md.power_save = idle; +} + /* * The body of the idle task. */ Index: linux.trees.git/include/linux/pm.h =================================================================== --- linux.trees.git.orig/include/linux/pm.h +++ linux.trees.git/include/linux/pm.h @@ -30,6 +30,16 @@ extern void (*pm_idle)(void); extern void (*pm_power_off)(void); extern void (*pm_power_off_prepare)(void); +struct idle_function_desc { + char *name; + void (*idle_func)(void); + struct list_head idle_list; +}; + +extern void set_arch_idle(void (*idle)(void)); +extern void register_idle_function(struct idle_function_desc *desc); +extern void unregister_idle_function(struct idle_function_desc *desc); + /* * Device power management */ Index: linux.trees.git/drivers/cpuidle/cpuidle.c =================================================================== --- linux.trees.git.orig/drivers/cpuidle/cpuidle.c +++ linux.trees.git/drivers/cpuidle/cpuidle.c @@ -44,6 +44,43 @@ static void cpuidle_kick_cpus(void) static void cpuidle_kick_cpus(void) {} #endif +LIST_HEAD(idle_function_list); +static DEFINE_MUTEX(idle_list_mutex); + +void register_idle_function(struct idle_function_desc *desc) +{ + mutex_lock(&idle_list_mutex); + + list_add(&desc->idle_list, &idle_function_list); + set_arch_idle(desc->idle_func); + cpuidle_kick_cpus(); + + mutex_unlock(&idle_list_mutex); +} + +void unregister_idle_function(struct idle_function_desc *desc) +{ + struct list_head *pos; + struct idle_function_desc *temp_desc; + + mutex_lock(&idle_list_mutex); + WARN_ON_ONCE(list_empty(&desc->idle_list) || desc != NULL); + + list_for_each(pos, &idle_function_list) { + temp_desc = container_of(pos, struct idle_function_desc, + idle_list); + if (temp_desc == desc) { + list_del(&temp_desc->idle_list); + /* Re-using temp_desc here */ + temp_desc = list_first_entry(&idle_function_list, + struct idle_function_desc, idle_list); + set_arch_idle(temp_desc->idle_func); + cpuidle_kick_cpus(); + } + } + mutex_unlock(&idle_list_mutex); +} + static int __cpuidle_register_device(struct cpuidle_device *dev); /**