From patchwork Wed Oct 31 16:44:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Lezcano X-Patchwork-Id: 1680331 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 93C9BDFE75 for ; Wed, 31 Oct 2012 16:45:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758299Ab2JaQpN (ORCPT ); Wed, 31 Oct 2012 12:45:13 -0400 Received: from mail-bk0-f46.google.com ([209.85.214.46]:35944 "EHLO mail-bk0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758120Ab2JaQpG (ORCPT ); Wed, 31 Oct 2012 12:45:06 -0400 Received: by mail-bk0-f46.google.com with SMTP id jk13so767932bkc.19 for ; Wed, 31 Oct 2012 09:45:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=Mdqr9u7ROXqHtEsSpBiBJupqvwxORAugNwzO2NiVKfc=; b=l2Bu0ClvmivSrzdyztND+fWTbcPUrBt+SpONAWdkSPNzuDbkfPrtevGfQ2WxNgPLp8 olwv6A+2dpi2UbU9S5Hphb2AxC7nKSfkULvoBuErbWQ2a2JNGFceroOsEr1THpizE79d h/KYDsVu72jun0kViept4O280aZHoBWqwNNw4AVwUSga+y9BEmbIchWncEgkJKhpQqMd VbM1+muF5Snfr3rHa+uvega1SFloYBGWIRdK+YZaQhVv359ZQgOROWq4Kio5AUXDqcf8 SRmiqSFtNUy/lkejRbCF3eHH5z9Ob2ltaOUkQM73ZXvMM7qbVONnOAuiP8UBWwT+jwMu ZCRQ== Received: by 10.204.5.204 with SMTP id 12mr11641703bkw.89.1351701905844; Wed, 31 Oct 2012 09:45:05 -0700 (PDT) Received: from localhost.localdomain ([91.224.175.20]) by mx.google.com with ESMTPS id e13sm3909744bkw.12.2012.10.31.09.45.01 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 31 Oct 2012 09:45:04 -0700 (PDT) From: Daniel Lezcano To: rjw@sisk.pl Cc: linux-pm@vger.kernel.org, pdeschrijver@nvidia.com, lorenzo.pieralisi@arm.com, linaro-dev@lists.linaro.org Subject: [PATCH V3 3/4] cpuidle: prepare the driver core to be multi drivers aware Date: Wed, 31 Oct 2012 17:44:47 +0100 Message-Id: <1351701888-19963-4-git-send-email-daniel.lezcano@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1351701888-19963-1-git-send-email-daniel.lezcano@linaro.org> References: <1351701888-19963-1-git-send-email-daniel.lezcano@linaro.org> X-Gm-Message-State: ALoCoQkiUx1HjWG3603v4H7Ln3swCpncXiZ1a6tLFUiVquFTEYTSdifHw/wLzqik51YVEUk5OFJs Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This patch is a preparation for the multiple drivers support. As the next patch will introduce the multiple drivers with the Kconfig option and we want to keep the code clean and understandable, this patch defines a set of functions for encapsulating some common parts and split what should be done in a lock context or not. Signed-off-by: Daniel Lezcano Acked-by: Peter De Schrijver --- drivers/cpuidle/driver.c | 60 ++++++++++++++++++++++++++++++++------------- 1 files changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c index 3e59075..8246662 100644 --- a/drivers/cpuidle/driver.c +++ b/drivers/cpuidle/driver.c @@ -39,11 +39,20 @@ static void set_power_states(struct cpuidle_driver *drv) drv->states[i].power_usage = -1 - i; } -/** - * cpuidle_register_driver - registers a driver - * @drv: the driver - */ -int cpuidle_register_driver(struct cpuidle_driver *drv) +static void __cpuidle_driver_init(struct cpuidle_driver *drv) +{ + drv->refcnt = 0; + + if (!drv->power_specified) + set_power_states(drv); +} + +static void cpuidle_set_driver(struct cpuidle_driver *drv) +{ + cpuidle_curr_driver = drv; +} + +static int __cpuidle_register_driver(struct cpuidle_driver *drv) { if (!drv || !drv->state_count) return -EINVAL; @@ -51,22 +60,38 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) if (cpuidle_disabled()) return -ENODEV; - spin_lock(&cpuidle_driver_lock); - if (cpuidle_curr_driver) { - spin_unlock(&cpuidle_driver_lock); + if (cpuidle_get_driver()) return -EBUSY; - } - if (!drv->power_specified) - set_power_states(drv); + __cpuidle_driver_init(drv); - drv->refcnt = 0; + cpuidle_set_driver(drv); - cpuidle_curr_driver = drv; + return 0; +} + +static void __cpuidle_unregister_driver(struct cpuidle_driver *drv) +{ + if (drv != cpuidle_get_driver()) + return; + + if (!WARN_ON(drv->refcnt > 0)) + cpuidle_set_driver(NULL); +} +/** + * cpuidle_register_driver - registers a driver + * @drv: the driver + */ +int cpuidle_register_driver(struct cpuidle_driver *drv) +{ + int ret; + + spin_lock(&cpuidle_driver_lock); + ret = __cpuidle_register_driver(drv); spin_unlock(&cpuidle_driver_lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(cpuidle_register_driver); @@ -86,8 +111,7 @@ EXPORT_SYMBOL_GPL(cpuidle_get_driver); void cpuidle_unregister_driver(struct cpuidle_driver *drv) { spin_lock(&cpuidle_driver_lock); - if (drv == cpuidle_curr_driver && !WARN_ON(drv->refcnt > 0)) - cpuidle_curr_driver = NULL; + __cpuidle_unregister_driver(drv); spin_unlock(&cpuidle_driver_lock); } EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); @@ -98,7 +122,7 @@ struct cpuidle_driver *cpuidle_driver_ref(void) spin_lock(&cpuidle_driver_lock); - drv = cpuidle_curr_driver; + drv = cpuidle_get_driver(); drv->refcnt++; spin_unlock(&cpuidle_driver_lock); @@ -107,7 +131,7 @@ struct cpuidle_driver *cpuidle_driver_ref(void) void cpuidle_driver_unref(void) { - struct cpuidle_driver *drv = cpuidle_curr_driver; + struct cpuidle_driver *drv = cpuidle_get_driver(); spin_lock(&cpuidle_driver_lock);