From patchwork Mon Jan 23 04:41:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 9531723 X-Patchwork-Delegate: rjw@sisk.pl Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C07B76020B for ; Mon, 23 Jan 2017 04:42:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B1A91279E0 for ; Mon, 23 Jan 2017 04:42:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4C4227E3E; Mon, 23 Jan 2017 04:42:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 094F8279E0 for ; Mon, 23 Jan 2017 04:42:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751111AbdAWEmh (ORCPT ); Sun, 22 Jan 2017 23:42:37 -0500 Received: from mail-pg0-f48.google.com ([74.125.83.48]:34414 "EHLO mail-pg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751053AbdAWEmg (ORCPT ); Sun, 22 Jan 2017 23:42:36 -0500 Received: by mail-pg0-f48.google.com with SMTP id 14so41332491pgg.1 for ; Sun, 22 Jan 2017 20:42:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=ikDN4rjA8jdtBYRqcU1xxtrLYmUv2anxCDDe1sb1P00=; b=HrNkyKzatzF2W2BgzM2UPyF3GebQ93zU/Qoe0QRyvR5LcXahFhlMOSNdJPpM4H+TaE 2SZvBcdLi0pFFPc5S3kjQF5yeC7dmv9ba6C7fgz3hsunUgbelvxbK24/No4ru9lvkvSe +QwMd20UrZXxYRmkkkXx9fdo5uLr+qUNWjchA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=ikDN4rjA8jdtBYRqcU1xxtrLYmUv2anxCDDe1sb1P00=; b=bGmrNfH9bLwrZTBlMlq6aSPHCFtyq9T2nDGLiDUJzFFbnErwUVi/RLuIzBMkpXyiil Ps0SHl9aCmJZpkhLG0+WmhLdTvgc4vramFR8w2izX50L4semHOIGPcnhAI58/B3X/cTs h/TFJX3IV0AUN0kiw4BycAXbKLoEGM8PThFF3JrEh0urxfjPibvoOG5ckNsabSoSV8j+ PK+2DIF4mOfCZrtGG0ozCWtyndXxVjmoF5xxW/UImkIHaaG+K+O/EaRUhBc7ihzgIHM8 NaVz3i+GyRPt246AfYN648ZGb3dNl+udAoxqwMYMg9AxeAnCpWZpNLVvlC3CAmmEAoYH OMDQ== X-Gm-Message-State: AIkVDXI6sEYvC174ky4S1Gzs74Ro3zhuv9Uxy4jIXbPvpSm5QcLw5m/xGQwtPENIaOuikVVY X-Received: by 10.98.209.73 with SMTP id t9mr17044612pfl.9.1485146541318; Sun, 22 Jan 2017 20:42:21 -0800 (PST) Received: from localhost ([122.171.65.82]) by smtp.gmail.com with ESMTPSA id w76sm32635997pfd.74.2017.01.22.20.42.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Jan 2017 20:42:19 -0800 (PST) From: Viresh Kumar To: Rafael Wysocki , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org, Vincent Guittot , Viresh Kumar Subject: [PATCH V2 06/12] PM / OPP: Add 'struct kref' to struct dev_pm_opp Date: Mon, 23 Jan 2017 10:11:46 +0530 Message-Id: X-Mailer: git-send-email 2.7.1.410.g6faf27b In-Reply-To: References: In-Reply-To: References: Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add kref to struct dev_pm_opp for easier accounting of the OPPs. Note that the OPPs are freed under the opp_table->lock mutex only. Signed-off-by: Viresh Kumar Reviewed-by: Stephen Boyd --- drivers/base/power/opp/core.c | 27 ++++++++++++--------------- drivers/base/power/opp/opp.h | 3 +++ include/linux/pm_opp.h | 3 +++ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c index ab9499e3ba02..9870ee54d708 100644 --- a/drivers/base/power/opp/core.c +++ b/drivers/base/power/opp/core.c @@ -949,20 +949,10 @@ static void _kfree_opp_rcu(struct rcu_head *head) kfree_rcu(opp, rcu_head); } -/** - * _opp_remove() - Remove an OPP from a table definition - * @opp_table: points back to the opp_table struct this opp belongs to - * @opp: pointer to the OPP to remove - * - * This function removes an opp definition from the opp table. - * - * Locking: The internal opp_table and opp structures are RCU protected. - * It is assumed that the caller holds required mutex for an RCU updater - * strategy. - */ -static void _opp_remove(struct opp_table *opp_table, struct dev_pm_opp *opp) +static void _opp_kref_release(struct kref *kref) { - mutex_lock(&opp_table->lock); + struct dev_pm_opp *opp = container_of(kref, struct dev_pm_opp, kref); + struct opp_table *opp_table = opp->opp_table; /* * Notify the changes in the availability of the operable @@ -977,6 +967,12 @@ static void _opp_remove(struct opp_table *opp_table, struct dev_pm_opp *opp) dev_pm_opp_put_opp_table(opp_table); } +void dev_pm_opp_put(struct dev_pm_opp *opp) +{ + kref_put_mutex(&opp->kref, _opp_kref_release, &opp->opp_table->lock); +} +EXPORT_SYMBOL_GPL(dev_pm_opp_put); + /** * dev_pm_opp_remove() - Remove an OPP from OPP table * @dev: device for which we do this operation @@ -1020,7 +1016,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned long freq) goto unlock; } - _opp_remove(opp_table, opp); + dev_pm_opp_put(opp); unlock: mutex_unlock(&opp_table_lock); } @@ -1124,6 +1120,7 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, mutex_unlock(&opp_table->lock); new_opp->opp_table = opp_table; + kref_init(&new_opp->kref); /* Get a reference to the OPP table */ _get_opp_table_kref(opp_table); @@ -1819,7 +1816,7 @@ void _dev_pm_opp_remove_table(struct opp_table *opp_table, struct device *dev, /* Free static OPPs */ list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) { if (remove_all || !opp->dynamic) - _opp_remove(opp_table, opp); + dev_pm_opp_put(opp); } } else { _remove_opp_dev(_find_opp_dev(dev, opp_table), opp_table); diff --git a/drivers/base/power/opp/opp.h b/drivers/base/power/opp/opp.h index a01724363347..586f36f94e28 100644 --- a/drivers/base/power/opp/opp.h +++ b/drivers/base/power/opp/opp.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,7 @@ extern struct list_head opp_tables; * are protected by the opp_table_lock for integrity. * IMPORTANT: the opp nodes should be maintained in increasing * order. + * @kref: for reference count of the OPP. * @available: true/false - marks if this OPP as available or not * @dynamic: not-created from static DT entries. * @turbo: true if turbo (boost) OPP @@ -73,6 +75,7 @@ extern struct list_head opp_tables; */ struct dev_pm_opp { struct list_head node; + struct kref kref; bool available; bool dynamic; diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 99787cbcaab2..731d548657aa 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -102,6 +102,7 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq); +void dev_pm_opp_put(struct dev_pm_opp *opp); int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt); @@ -193,6 +194,8 @@ static inline struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, return ERR_PTR(-ENOTSUPP); } +static inline void dev_pm_opp_put(struct dev_pm_opp *opp) {} + static inline int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt) {