From patchwork Mon Apr 2 12:48:48 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 7572 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id D1AC623E00 for ; Mon, 2 Apr 2012 12:48:50 +0000 (UTC) Received: from mail-yw0-f52.google.com (mail-yw0-f52.google.com [209.85.213.52]) by fiordland.canonical.com (Postfix) with ESMTP id 31EFFA18AC6 for ; Mon, 2 Apr 2012 12:48:50 +0000 (UTC) Received: by yhpp61 with SMTP id p61so1263258yhp.11 for ; Mon, 02 Apr 2012 05:48:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:x-gm-message-state; bh=6R6hiNJCcgYK7SFn36SkNti8afwLF8CgB7A9UT/CZr4=; b=gyJ03ZoF8YXNzZRGtwvkzqSST624Z+KAGi1F4Q/NWoIqwCTgtqysDFCVr7IKPg6MIO RwwDhYxz1vYo6PvPJHWDf+TllPHOpAWxhY5ASvVUNNw+XJFou1pCtFzKISSndV/vNPN2 KsbKvhab9TY7Q0DCRiZ3dRHfVPzc5ZsHT5PIfJvEPoz/bNNOVNUAUDKmfF9hViRLsRHR apqKgVAMrLLJ8WGd8McA0neSOG7NOPutzMpGj+r1PnM4yw5Ic4mFQf0LNp1Q+DvMxAQe hc31P2aqbGM2Qo3rHNzuUwrcIqDHS+btbAlNroCQ6a3t6SYwFFCuYgd7pDBO2caOcMOF OWdQ== Received: by 10.50.207.5 with SMTP id ls5mr5260011igc.51.1333370929508; Mon, 02 Apr 2012 05:48:49 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.5.205 with SMTP id 13csp108452ibw; Mon, 2 Apr 2012 05:48:48 -0700 (PDT) Received: by 10.213.9.18 with SMTP id j18mr610280ebj.23.1333370928074; Mon, 02 Apr 2012 05:48:48 -0700 (PDT) Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by mx.google.com with ESMTPS id s74si18456801weq.56.2012.04.02.05.48.47 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 02 Apr 2012 05:48:48 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.212.178 is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) client-ip=209.85.212.178; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.212.178 is neither permitted nor denied by best guess record for domain of daniel.lezcano@linaro.org) smtp.mail=daniel.lezcano@linaro.org Received: by wibhq7 with SMTP id hq7so2122883wib.13 for ; Mon, 02 Apr 2012 05:48:46 -0700 (PDT) Received: by 10.180.88.169 with SMTP id bh9mr24999440wib.5.1333370926527; Mon, 02 Apr 2012 05:48:46 -0700 (PDT) Received: from localhost.localdomain (AToulouse-159-1-7-136.w90-60.abo.wanadoo.fr. [90.60.242.136]) by mx.google.com with ESMTPS id ex2sm54866544wib.8.2012.04.02.05.48.44 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 02 Apr 2012 05:48:45 -0700 (PDT) From: Daniel Lezcano To: lenb@kernel.org Cc: linux-pm@lists.linux-foundation.org, linaro-dev@lists.linaro.org, patches@linaro.org, srivatsa.bhat@linux.vnet.ibm.com, daniel.lezcano@linaro.org Subject: [PATCH][V2] cpuidle : use percpu cpuidle in the core code Date: Mon, 2 Apr 2012 14:48:48 +0200 Message-Id: <1333370928-1930-1-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.5.4 X-Gm-Message-State: ALoCoQlnniXYhmiC2/8QRnO6Vsxq+o7FBNYIKygHoU6iFuU1+5y4Yx+VFwLkj5F44ZpAZrfkkJjP The usual cpuidle initialization routines are to register the driver, then register a cpuidle device per cpu. With the device's state count default initialization with the driver's state count, the code initialization remains mostly the same in the different drivers. We can then add a new function 'cpuidle_register' where we register the driver and the devices. These devices can be defined in a global static variable in cpuidle.c. We will be able to factor out and remove a lot of duplicate lines of code. As we still have some drivers, with different initialization routines, we keep 'cpuidle_register_driver' and 'cpuidle_register_device' as low level initialization routines to do some specific operations on the cpuidle devices. Signed-off-by: Daniel Lezcano --- drivers/cpuidle/cpuidle.c | 42 ++++++++++++++++++++++++++++++++++++++++++ include/linux/cpuidle.h | 3 +++ 2 files changed, 45 insertions(+), 0 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 87411ce..151c55a 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -23,6 +23,7 @@ #include "cpuidle.h" DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); +DEFINE_PER_CPU(struct cpuidle_device, cpuidle_device); DEFINE_MUTEX(cpuidle_lock); LIST_HEAD(cpuidle_detected_devices); @@ -419,6 +420,47 @@ int cpuidle_register_device(struct cpuidle_device *dev) EXPORT_SYMBOL_GPL(cpuidle_register_device); +/* + * cpuidle_register : register cpuidle driver and devices + * Note this function must be called after smp_init. + * @drv : the cpuidle driver + * Returns 0 on success, < 0 otherwise + */ +int cpuidle_register(struct cpuidle_driver *drv) +{ + int ret, cpu, i; + struct cpuidle_device *dev; + + ret = cpuidle_register_driver(drv); + if (ret) + return ret; + + for_each_online_cpu(cpu) { + dev = &per_cpu(cpuidle_device, cpu); + dev->cpu = cpu; + + ret = cpuidle_register_device(dev); + if (ret) + goto out_unregister; + } + +out: + return ret; + +out_unregister: + for_each_online_cpu(i) { + if (i == cpu) + break; + dev = &per_cpu(cpuidle_device, cpu); + cpuidle_unregister_device(dev); + } + + cpuidle_unregister_driver(drv); + + goto out; +} +EXPORT_SYMBOL_GPL(cpuidle_register); + /** * cpuidle_unregister_device - unregisters a CPU's idle PM feature * @dev: the cpu diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 6c26a3d..3475294 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -135,6 +135,7 @@ struct cpuidle_driver { #ifdef CONFIG_CPU_IDLE extern void disable_cpuidle(void); extern int cpuidle_idle_call(void); +extern int cpuidle_register(struct cpuidle_driver *drv); 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); @@ -154,6 +155,8 @@ extern int cpuidle_play_dead(void); #else static inline void disable_cpuidle(void) { } static inline int cpuidle_idle_call(void) { return -ENODEV; } +static inline int cpuidle_register(struct cpuidle_driver *drv) +{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; }