From patchwork Mon Apr 2 19:20:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 7576 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 6689C19920F for ; Mon, 2 Apr 2012 19:20:03 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 0C6CCA18267 for ; Mon, 2 Apr 2012 19:20:02 +0000 (UTC) Received: by iage36 with SMTP id e36so6428113iag.11 for ; Mon, 02 Apr 2012 12:20:02 -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=MLuhulp2Z3JiVbc0FlzKcpD73NmPcx5V/c2WXzIZiAc=; b=dSRLKPo2QwuI4jQJy36X9MFBwh2KR1UlpOwZoqBTlW/MKphrc2rSZfPHbmNh+iHzWQ MfmkkQmKAYyxR1GyKaWwzGzd8flaJrKvzvTxo35jriG+u4uPH3Grm0XqBPLT2mlr48SK qZYfK/YU4bWuzGsNUmGg9Ou8ukc2gpIfdYBZa8eaA10InvNYZ5rt65GukAG3lantTxZK LFWoB7D31oEVAavSnd6xljSaxiYpBWDD06qCpYVDupCcOcx9U6LzXeKX3pg2rLbfoUwh MRiT8BUV/sbNDBjzZV1Ic2loLOJeyfB6mR74hGJjvbfIU/r1bIoTh7GmZgIAUmFyeFHb yA7A== Received: by 10.50.42.132 with SMTP id o4mr6668981igl.41.1333394402496; Mon, 02 Apr 2012 12:20:02 -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 13csp129009ibw; Mon, 2 Apr 2012 12:20:01 -0700 (PDT) Received: by 10.180.73.143 with SMTP id l15mr27971422wiv.11.1333394400301; Mon, 02 Apr 2012 12:20:00 -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 v2si19683892weq.39.2012.04.02.12.19.59 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 02 Apr 2012 12:20:00 -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 hq7so2421610wib.13 for ; Mon, 02 Apr 2012 12:19:59 -0700 (PDT) Received: by 10.180.91.165 with SMTP id cf5mr28039741wib.2.1333394399174; Mon, 02 Apr 2012 12:19:59 -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 gd4sm58771672wib.6.2012.04.02.12.19.57 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 02 Apr 2012 12:19:58 -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][V3] cpuidle : use percpu cpuidle in the core code Date: Mon, 2 Apr 2012 21:20:01 +0200 Message-Id: <1333394401-20701-1-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.5.4 X-Gm-Message-State: ALoCoQkVF7uRmL7ivC+H1IkthQ8GBHVr9AZbnSaNmnD+FrqQwTI2/18+Ub2JSmaW1181FDpzluiY The usual cpuidle initialization routines register the driver and then register a cpuidle device per cpu. By default, most drivers initialize the device state count with the driver state count. 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 Acked-by: Srivatsa S. Bhat --- 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..4d1f79b 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, i); + 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; }