From patchwork Wed Jul 17 22:23:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11048285 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4706746 for ; Wed, 17 Jul 2019 22:24:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D307F212BE for ; Wed, 17 Jul 2019 22:24:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C76642877F; Wed, 17 Jul 2019 22:24:20 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham 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 7296C212BE for ; Wed, 17 Jul 2019 22:24:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729208AbfGQWXz (ORCPT ); Wed, 17 Jul 2019 18:23:55 -0400 Received: from mail-qk1-f201.google.com ([209.85.222.201]:49310 "EHLO mail-qk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727410AbfGQWXy (ORCPT ); Wed, 17 Jul 2019 18:23:54 -0400 Received: by mail-qk1-f201.google.com with SMTP id l14so21387425qke.16 for ; Wed, 17 Jul 2019 15:23:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=g20bmVhjq9PwMxcUgTHaVxhylFvIUYxFTb/7hfeQpvk=; b=D9RoywcPL8rsZqz0bMu7/+OwR+2YE29yOrq24BR0n6XZX58xaU1+khGkXQfJ7oOrIo JC6j6V1utL/bt3TA4HQOwyw39KP7TWDKDm5wD2IE9eEaXDow6O5bqk5GDgZvql6OOEP0 le0dUMPCh9Smyn8D8kWQ/Dot1jyfKG5pb27a66PvBMZpA1QHJjgTC+MIiSiqy3+afTXa yNFl54jamNGQ9OdLQn/d0K3fIDW5onBbqY5cFOW0g2A1Ag7QJLZcnh8hvcuM0LhnW5cb vJOIFuenmpajn3YaEaxIqKP6JNQJfOI7/bEUrvmu8fAuhDt3pwKA6y7BBCw4CEwe07dk XxVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=g20bmVhjq9PwMxcUgTHaVxhylFvIUYxFTb/7hfeQpvk=; b=aJmMGY1r37T+Iudkx12ucnmuQx5wVfCyEvfiuTuSoNkU5vtqA6GrL3JRgPlIhW0NbM q7FL3ebVmXLFPgcmwp/wo6Ikw4o2sSeAisfkZ9MvKGBvfA9Xya794ks8rJxz/zebDcDc 5ZtWrcGfQZPorx8QMjw6LUhe6pLPfuUKDoUFHxlPXBhFD8k8YQUabvkOozuACukwz6oG fRFhwl++zpu6QrjCYg/SPA47iqUiFb1ulclK4cITG3pR7OshPnVLnFnqINsA7R7sbEcH Gk1zHaH77V+eEsYdYigHIuihUxGG8ER1ciN2km6hXAENVt/xHRIjWpGvEzsMbfl9GlOC qH8A== X-Gm-Message-State: APjAAAULw2h5jOboRl2ednqPgoCLBgSUwDQJzvonjmRVZloCmDhgsWFS S0ZazLDtXgemY8lIli1kXPZamnmycl99ixM= X-Google-Smtp-Source: APXvYqwz8KDML9VvH5pH0LJQsWloxsFAnC07TtA1W+tW5SM8ax4Yi/o76+L7uXmhgURWW0WrEThWjBifw5lWqiM= X-Received: by 2002:ae9:de87:: with SMTP id s129mr26896239qkf.485.1563402233331; Wed, 17 Jul 2019 15:23:53 -0700 (PDT) Date: Wed, 17 Jul 2019 15:23:36 -0700 In-Reply-To: <20190717222340.137578-1-saravanak@google.com> Message-Id: <20190717222340.137578-2-saravanak@google.com> Mime-Version: 1.0 References: <20190717222340.137578-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [PATCH v3 1/5] OPP: Allow required-opps even if the device doesn't have power-domains From: Saravana Kannan To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Saravana Kannan , Sibi Sankar , kernel-team@android.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org 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 A Device-A can have a (minimum) performance requirement on another Device-B to be able to function correctly. This performance requirement on Device-B can also change based on the current performance level of Device-A. The existing required-opps feature fits well to describe this need. So, instead of limiting required-opps to point to only PM-domain devices, allow it to point to any device. Signed-off-by: Saravana Kannan --- drivers/opp/core.c | 2 +- drivers/opp/of.c | 11 ----------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index c094d5d20fd7..438fcd134d93 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -707,7 +707,7 @@ static int _set_required_opps(struct device *dev, return 0; /* Single genpd case */ - if (!genpd_virt_devs) { + if (!genpd_virt_devs && required_opp_tables[0]->is_genpd) { pstate = likely(opp) ? opp->required_opps[0]->pstate : 0; ret = dev_pm_genpd_set_performance_state(dev, pstate); if (ret) { diff --git a/drivers/opp/of.c b/drivers/opp/of.c index b313aca9894f..ff88eaf66b56 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -197,17 +197,6 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, if (IS_ERR(required_opp_tables[i])) goto free_required_tables; - - /* - * We only support genpd's OPPs in the "required-opps" for now, - * as we don't know how much about other cases. Error out if the - * required OPP doesn't belong to a genpd. - */ - if (!required_opp_tables[i]->is_genpd) { - dev_err(dev, "required-opp doesn't belong to genpd: %pOF\n", - required_np); - goto free_required_tables; - } } goto put_np; From patchwork Wed Jul 17 22:23:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11048279 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D17FE13BD for ; Wed, 17 Jul 2019 22:24:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BFCB3212BE for ; Wed, 17 Jul 2019 22:24:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B40152877F; Wed, 17 Jul 2019 22:24:04 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham 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 4B48D286B0 for ; Wed, 17 Jul 2019 22:24:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729022AbfGQWX6 (ORCPT ); Wed, 17 Jul 2019 18:23:58 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:32967 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729723AbfGQWX5 (ORCPT ); Wed, 17 Jul 2019 18:23:57 -0400 Received: by mail-pg1-f201.google.com with SMTP id a21so8586661pgv.0 for ; Wed, 17 Jul 2019 15:23:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7ut4pV8VU2XMvAiC0EUAug5uzDTyE8K6amY1HkNFP0k=; b=O70FLfpIET7sMGLffRwo9AG66vfmK6/bnvOuCCmJJljFc5byVD6IxQzah2oKNGO1MX If8mLMWT2xN01n97Sdv+4N2ZIz7/t4N6FFW+j1wRyw60Oj+yZ+T1Cf9laQ1gzrXFRGXf C8pcBSw2jxl8JJzTwshcULF8NjGFZkIGv8vzLSK9hNMDAKnMTn2gznqaCTtXyW6jp9k3 MdlWdVJKOCGmzC5xaHBp3YNAcZYwy4cb8+AMd9Q2xdYl3DzhzEsav8qwDeoz1iXXTzKB GEOifcTdRKauqamU4ynDhamTF5T6eo7kCix4f6d4+md2JcKcFxZN7dwRIuIbPJ3uODZo MPww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7ut4pV8VU2XMvAiC0EUAug5uzDTyE8K6amY1HkNFP0k=; b=Al2qfuI8m2d7/mFcrRGOmkwU6S0TAU9MrAMO5rffTGG9LUp1rz7fPw22J6uUcAthKx TO12voXSneeAGgRnUgvg0I5iXalaW9OdLxxJ61puDu4L/iI4N06YJmCYi/4/gQx8cqE3 hRIckOlu2yukDYbWjgHOLJ6u6i+oVek7D1Y69fxJ0Vo3ExMdR2afcAoQVYhG6w4/BTBP UAwR9EA1ILj5kBZtgnnExsiyKGfR4vaukqbv9OlIjqDU/LGLtawP5J8dxUwkuav120eZ HS2Suo4w8b14yuiet6A6e/Uc4dsq2ZMJlL58oX/pHZRT8lfRJIFxY6e4NHE+/hZc5Gy+ vU5g== X-Gm-Message-State: APjAAAUN/qEGi8lqqDGTUv6Vft7osPCp+xhFQSzjCgBHdsNET6BVfFOp neV3FmQ+NKzWCJKlTc0nAktwGV1YPeePo94= X-Google-Smtp-Source: APXvYqxpyhog97eYpe3tvuoeEK3ZGMJGr/4T2l9mqy6Eov3lFXO4Yz0bxpt58Gu+SD0h2HiGys1wFILZH+fiExc= X-Received: by 2002:a63:d415:: with SMTP id a21mr42685588pgh.229.1563402236508; Wed, 17 Jul 2019 15:23:56 -0700 (PDT) Date: Wed, 17 Jul 2019 15:23:37 -0700 In-Reply-To: <20190717222340.137578-1-saravanak@google.com> Message-Id: <20190717222340.137578-3-saravanak@google.com> Mime-Version: 1.0 References: <20190717222340.137578-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [PATCH v3 2/5] OPP: Add function to look up required OPP's for a given OPP From: Saravana Kannan To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Saravana Kannan , Sibi Sankar , kernel-team@android.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org 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 a function that allows looking up required OPPs given a source OPP table, destination OPP table and the source OPP. Signed-off-by: Saravana Kannan --- drivers/opp/core.c | 54 ++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 11 +++++++++ 2 files changed, 65 insertions(+) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 438fcd134d93..72c055a3f6b7 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1883,6 +1883,60 @@ void dev_pm_opp_detach_genpd(struct opp_table *opp_table) } EXPORT_SYMBOL_GPL(dev_pm_opp_detach_genpd); +/** + * dev_pm_opp_xlate_opp() - Find required OPP for src_table OPP. + * @src_table: OPP table which has dst_table as one of its required OPP table. + * @dst_table: Required OPP table of the src_table. + * @pstate: OPP of the src_table. + * + * This function returns the OPP (present in @dst_table) pointed out by the + * "required-opps" property of the OPP (present in @src_table). + * + * The callers are required to call dev_pm_opp_put() for the returned OPP after + * use. + * + * Return: destination table OPP on success, otherwise NULL on errors. + */ +struct dev_pm_opp *dev_pm_opp_xlate_opp(struct opp_table *src_table, + struct opp_table *dst_table, + struct dev_pm_opp *src_opp) +{ + struct dev_pm_opp *opp, *dest_opp = NULL; + int i; + + if (!src_table || !dst_table || !src_opp) + return NULL; + + for (i = 0; i < src_table->required_opp_count; i++) { + if (src_table->required_opp_tables[i]->np == dst_table->np) + break; + } + + if (unlikely(i == src_table->required_opp_count)) { + pr_err("%s: Couldn't find matching OPP table (%p: %p)\n", + __func__, src_table, dst_table); + return NULL; + } + + mutex_lock(&src_table->lock); + + list_for_each_entry(opp, &src_table->opp_list, node) { + if (opp == src_opp) { + dest_opp = opp->required_opps[i]; + dev_pm_opp_get(dest_opp); + goto unlock; + } + } + + pr_err("%s: Couldn't find matching OPP (%p: %p)\n", __func__, src_table, + dst_table); + +unlock: + mutex_unlock(&src_table->lock); + + return dest_opp; +} + /** * dev_pm_opp_xlate_performance_state() - Find required OPP's pstate for src_table. * @src_table: OPP table which has dst_table as one of its required OPP table. diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index af5021f27cb7..36f52b9cf24a 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -131,6 +131,9 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names); void dev_pm_opp_detach_genpd(struct opp_table *opp_table); int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); +struct dev_pm_opp *dev_pm_opp_xlate_opp(struct opp_table *src_table, + struct opp_table *dst_table, + struct dev_pm_opp *src_opp); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); @@ -304,6 +307,14 @@ static inline int dev_pm_opp_xlate_performance_state(struct opp_table *src_table return -ENOTSUPP; } +static inline struct dev_pm_opp *dev_pm_opp_xlate_opp( + struct opp_table *src_table, + struct opp_table *dst_table, + struct dev_pm_opp *src_opp) +{ + return NULL; +} + static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) { return -ENOTSUPP; From patchwork Wed Jul 17 22:23:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11048277 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8BB39746 for ; Wed, 17 Jul 2019 22:24:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BBA2212BE for ; Wed, 17 Jul 2019 22:24:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F2D128787; Wed, 17 Jul 2019 22:24:04 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham 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 B68B0212BE for ; Wed, 17 Jul 2019 22:24:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729982AbfGQWYC (ORCPT ); Wed, 17 Jul 2019 18:24:02 -0400 Received: from mail-pl1-f201.google.com ([209.85.214.201]:56668 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729981AbfGQWYB (ORCPT ); Wed, 17 Jul 2019 18:24:01 -0400 Received: by mail-pl1-f201.google.com with SMTP id o6so12760467plk.23 for ; Wed, 17 Jul 2019 15:24:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JiAbZiQnbypR/LQybLeRQSTrO5YSwCRzRThmbb4fRO4=; b=RxtfqxJJQCxHBT9Iiw0njIWJClOh8QwW25XIFpBmKbrv2XIyKvW5AcTQUfvMwG0+mo rSfFbo1IJO6m4VClRpz3n+Z46BHDsBNJH7T9FRlcdliia/Zd7uekHwT/nnOzVfcW2lhg /cDhYTmQRC66zI8ZQeewrUixTAHTS71GvYo30xB+ZEJT1SQNTyPgyHizjeyGnZDnWTAM J8zJDCgWwIXKAWIfuge54XUabefVdcWElHSU/jxjwwrtEy6YJhGyPV+CykMBO8yTKnhh EG3AjIPnV7MCrq9pWQoeVadiPeen0VwUyAyGr4F+Eyb/uu9J+ZZG0mRnoRZNEPM1Lclk nrZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JiAbZiQnbypR/LQybLeRQSTrO5YSwCRzRThmbb4fRO4=; b=VzxRpVfLZCQv1xJANQAaXwa/9C3STlNWG+M64x0P0rkyck9Xxwkv/I+nI32Tf0ca8d UsKAtLo+nMkHNVME5wUKurYgxX051fQOSz3d/xiYFmll7cRLXFaHHHOggC01tDoQ/1i0 O806mS6vvAGxzfkvXu+q5W6AwDlT24cCQ8zkiXONwjpcsLUCfqH/z08eB+He4jYAeSrJ ZuYabIYrCKpBnCdrEm//gqmN9/0/z3PDpUTJjjhtA96HB+WJUyq+BNHIQsE254P1prLr +QBLUB8bZTC2wTUfN6sr/rU0xG9cWbTwy6F1bu0X8jMMqMvNS/OeF5pPcWYA0R9mkLeO bKbQ== X-Gm-Message-State: APjAAAWlBZeLM7+el/NxVGt2VZhDf3iiFJh5k3g/s2J2WQPaHTE7Zhij cDMYg2y5edM8M70NEFrj0hNY7h1AHW3Zd5k= X-Google-Smtp-Source: APXvYqzkmV2/dNoDj5VZu6rSEzqoc8mWaBfmF+nBWnlSTgiXQA+nqeoaREf7O5pqaS6PzjWwwpt3iyc4KPkSWz8= X-Received: by 2002:a63:fb14:: with SMTP id o20mr32641083pgh.136.1563402240173; Wed, 17 Jul 2019 15:24:00 -0700 (PDT) Date: Wed, 17 Jul 2019 15:23:38 -0700 In-Reply-To: <20190717222340.137578-1-saravanak@google.com> Message-Id: <20190717222340.137578-4-saravanak@google.com> Mime-Version: 1.0 References: <20190717222340.137578-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [PATCH v3 3/5] OPP: Improve require-opps linking From: Saravana Kannan To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Saravana Kannan , Sibi Sankar , kernel-team@android.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org 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 Currently, the linking of required-opps fails silently if the destination OPP table hasn't been added before the source OPP table is added. This puts an unnecessary requirement that the destination table be added before the source table is added. In reality, the destination table is needed only when we try to translate from source OPP to destination OPP. So, instead of completely failing, retry linking the tables when the translation is attempted. Signed-off-by: Saravana Kannan Signed-off-by: Viresh Kumar Reviewed-by: Sibi Sankar Tested-by: Sibi Sankar Signed-off-by: Viresh Kumar Tested-by: Hsin-Yi Wang --- drivers/opp/core.c | 32 +++++++++++----- drivers/opp/of.c | 91 ++++++++++++++++++++++------------------------ drivers/opp/opp.h | 5 +++ 3 files changed, 71 insertions(+), 57 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 72c055a3f6b7..cafe6ec05d6c 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -706,8 +706,11 @@ static int _set_required_opps(struct device *dev, if (!required_opp_tables) return 0; + _of_lazy_link_required_tables(opp_table); + /* Single genpd case */ - if (!genpd_virt_devs && required_opp_tables[0]->is_genpd) { + if (!genpd_virt_devs && required_opp_tables[0] + && required_opp_tables[0]->is_genpd) { pstate = likely(opp) ? opp->required_opps[0]->pstate : 0; ret = dev_pm_genpd_set_performance_state(dev, pstate); if (ret) { @@ -726,11 +729,16 @@ static int _set_required_opps(struct device *dev, mutex_lock(&opp_table->genpd_virt_dev_lock); for (i = 0; i < opp_table->required_opp_count; i++) { - pstate = likely(opp) ? opp->required_opps[i]->pstate : 0; - if (!genpd_virt_devs[i]) continue; + if (!opp->required_opps[i]) { + ret = -ENODEV; + break; + } + + pstate = likely(opp) ? opp->required_opps[i]->pstate : 0; + ret = dev_pm_genpd_set_performance_state(genpd_virt_devs[i], pstate); if (ret) { dev_err(dev, "Failed to set performance rate of %s: %d (%d)\n", @@ -1907,8 +1915,11 @@ struct dev_pm_opp *dev_pm_opp_xlate_opp(struct opp_table *src_table, if (!src_table || !dst_table || !src_opp) return NULL; + _of_lazy_link_required_tables(src_table); + for (i = 0; i < src_table->required_opp_count; i++) { - if (src_table->required_opp_tables[i]->np == dst_table->np) + if (src_table->required_opp_tables[i] + && src_table->required_opp_tables[i]->np == dst_table->np) break; } @@ -1971,6 +1982,8 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, if (!src_table->required_opp_count) return pstate; + _of_lazy_link_required_tables(src_table); + for (i = 0; i < src_table->required_opp_count; i++) { if (src_table->required_opp_tables[i]->np == dst_table->np) break; @@ -1986,15 +1999,16 @@ int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, list_for_each_entry(opp, &src_table->opp_list, node) { if (opp->pstate == pstate) { - dest_pstate = opp->required_opps[i]->pstate; - goto unlock; + if (opp->required_opps[i]) + dest_pstate = opp->required_opps[i]->pstate; + break; } } - pr_err("%s: Couldn't find matching OPP (%p: %p)\n", __func__, src_table, - dst_table); + if (dest_pstate < 0) + pr_err("%s: Couldn't find matching OPP (%p: %p)\n", __func__, + src_table, dst_table); -unlock: mutex_unlock(&src_table->lock); return dest_pstate; diff --git a/drivers/opp/of.c b/drivers/opp/of.c index ff88eaf66b56..4e527245fd59 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -145,7 +145,7 @@ static void _opp_table_free_required_tables(struct opp_table *opp_table) for (i = 0; i < opp_table->required_opp_count; i++) { if (IS_ERR_OR_NULL(required_opp_tables[i])) - break; + continue; dev_pm_opp_put_opp_table(required_opp_tables[i]); } @@ -165,8 +165,8 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, struct device_node *opp_np) { struct opp_table **required_opp_tables; - struct device_node *required_np, *np; - int count, i; + struct device_node *np; + int count; /* Traversing the first OPP node is all we need */ np = of_get_next_available_child(opp_np, NULL); @@ -176,35 +176,57 @@ static void _opp_table_alloc_required_tables(struct opp_table *opp_table, } count = of_count_phandle_with_args(np, "required-opps", NULL); + of_node_put(np); if (!count) - goto put_np; + return; required_opp_tables = kcalloc(count, sizeof(*required_opp_tables), GFP_KERNEL); if (!required_opp_tables) - goto put_np; + return; opp_table->required_opp_tables = required_opp_tables; opp_table->required_opp_count = count; +} - for (i = 0; i < count; i++) { - required_np = of_parse_required_opp(np, i); - if (!required_np) - goto free_required_tables; +void _of_lazy_link_required_tables(struct opp_table *src) +{ + struct dev_pm_opp *src_opp, *tmp_opp; + struct opp_table *req_table; + struct device_node *req_np; + int i; - required_opp_tables[i] = _find_table_of_opp_np(required_np); - of_node_put(required_np); + mutex_lock(&src->lock); - if (IS_ERR(required_opp_tables[i])) - goto free_required_tables; - } + if (list_empty(&src->opp_list)) + goto out; - goto put_np; + src_opp = list_first_entry(&src->opp_list, struct dev_pm_opp, node); -free_required_tables: - _opp_table_free_required_tables(opp_table); -put_np: - of_node_put(np); + for (i = 0; i < src->required_opp_count; i++) { + if (src->required_opp_tables[i]) + continue; + + req_np = of_parse_required_opp(src_opp->np, i); + if (!req_np) + continue; + + req_table = _find_table_of_opp_np(req_np); + of_node_put(req_np); + if (!req_table) + continue; + + src->required_opp_tables[i] = req_table; + list_for_each_entry(tmp_opp, &src->opp_list, node) { + req_np = of_parse_required_opp(tmp_opp->np, i); + tmp_opp->required_opps[i] = _find_opp_of_np(req_table, + req_np); + of_node_put(req_np); + } + } + +out: + mutex_unlock(&src->lock); } void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, @@ -267,7 +289,7 @@ void _of_opp_free_required_opps(struct opp_table *opp_table, for (i = 0; i < opp_table->required_opp_count; i++) { if (!required_opps[i]) - break; + continue; /* Put the reference back */ dev_pm_opp_put(required_opps[i]); @@ -282,9 +304,7 @@ static int _of_opp_alloc_required_opps(struct opp_table *opp_table, struct dev_pm_opp *opp) { struct dev_pm_opp **required_opps; - struct opp_table *required_table; - struct device_node *np; - int i, ret, count = opp_table->required_opp_count; + int count = opp_table->required_opp_count; if (!count) return 0; @@ -295,32 +315,7 @@ static int _of_opp_alloc_required_opps(struct opp_table *opp_table, opp->required_opps = required_opps; - for (i = 0; i < count; i++) { - required_table = opp_table->required_opp_tables[i]; - - np = of_parse_required_opp(opp->np, i); - if (unlikely(!np)) { - ret = -ENODEV; - goto free_required_opps; - } - - required_opps[i] = _find_opp_of_np(required_table, np); - of_node_put(np); - - if (!required_opps[i]) { - pr_err("%s: Unable to find required OPP node: %pOF (%d)\n", - __func__, opp->np, i); - ret = -ENODEV; - goto free_required_opps; - } - } - return 0; - -free_required_opps: - _of_opp_free_required_opps(opp_table, opp); - - return ret; } static bool _opp_is_supported(struct device *dev, struct opp_table *opp_table, diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 01a500e2c40a..5b074eb7da07 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -225,12 +225,17 @@ void _of_clear_opp_table(struct opp_table *opp_table); struct opp_table *_managed_opp(struct device *dev, int index); void _of_opp_free_required_opps(struct opp_table *opp_table, struct dev_pm_opp *opp); +void _of_lazy_link_required_tables(struct opp_table *src); #else static inline void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index) {} static inline void _of_clear_opp_table(struct opp_table *opp_table) {} static inline struct opp_table *_managed_opp(struct device *dev, int index) { return NULL; } static inline void _of_opp_free_required_opps(struct opp_table *opp_table, struct dev_pm_opp *opp) {} +void bool _of_lazy_link_required_tables(struct opp_table *src) +{ + return false; +} #endif #ifdef CONFIG_DEBUG_FS From patchwork Wed Jul 17 22:23:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11048283 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 65F0D746 for ; Wed, 17 Jul 2019 22:24:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53D3E212BE for ; Wed, 17 Jul 2019 22:24:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 45EED2877F; Wed, 17 Jul 2019 22:24:19 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham 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 DD52A212BE for ; Wed, 17 Jul 2019 22:24:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730024AbfGQWYR (ORCPT ); Wed, 17 Jul 2019 18:24:17 -0400 Received: from mail-vs1-f74.google.com ([209.85.217.74]:42128 "EHLO mail-vs1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730006AbfGQWYE (ORCPT ); Wed, 17 Jul 2019 18:24:04 -0400 Received: by mail-vs1-f74.google.com with SMTP id a11so6122745vso.9 for ; Wed, 17 Jul 2019 15:24:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=hlgN2kJF8O2fjyDEv3zuJRNqQ1+92Wl3CueXhQyVzIU=; b=NnRzkWoN5/S27nZtGN8yKD37RUeIb30TAYui+l8MKkJjjOT5PipUtajEOAMDk3YNoc 8PTBCgW0yWc1MCot3JFGVlX5HzIjsbmZczGK5SNXBXM6xPTUEjTFyzzAUFh66LXRZ2yf V49f5emTq5XuK2SSmMsDaN20WSehh/hCsKJ+cnTyJvPTXH6CtdFx0vRDarSfmgThKmdz bNj4bz2ocVw0o9Loue41WzGw0CyLlFFVs/s8DwT3wOQgsYug5wJZjnxA0QwV55V6XxDF JRjsdyUDNLiB5KUNQtrXX51GVqXwEjhJvFrupEnXsyMIpNF0B3yA23l9dvCmdFsRQZ2u Zo+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=hlgN2kJF8O2fjyDEv3zuJRNqQ1+92Wl3CueXhQyVzIU=; b=o0jy5rZfXf+7TgcLmgA9ziNk6rYWvZnhVXEjf9RL6N1eoQWQ8K46W60qZgK0Q4tlLy 87Nlher9TN2uL9nsiPZjWDdpAb1F6Rl+PPojNsAIY7mh9h4mhoDar6PO+UGYbaI9CxKH tU6HUUGmuYb7aKVKqCWprE7vTRhsOIHTyo8gl4IIN0qDZOBv/E7hq6EDOQbDziesLwEq q0SI0FbgE9gUtyfFLEOdDQlRsDMPzQRgPofbuT3PVnWH2G14btBtzrwkN3mkEASECRiz 3Na/bJif7ZNPwsfCSTJr0Gy0hK14lkAj5zAqm8/q7CFej4wmG8qfi7cdP7tvsSKJSUe1 3OQA== X-Gm-Message-State: APjAAAVAERxJqXsl5FNBSdIMgwxVJFBSHNtLoNGqBvrUFMEboYBAixPV s25ovWb6AYabmH9huri0ypwOZUBwwzQthBo= X-Google-Smtp-Source: APXvYqxT7Vys34+uPXtEl++ZtCFPgc1bYc+kkS7nUGHqMGkJzXWLXdIw67qCU6GNH5aCIzUf7VLs2KSSKQQV+0o= X-Received: by 2002:a1f:6e8e:: with SMTP id j136mr17525706vkc.80.1563402243539; Wed, 17 Jul 2019 15:24:03 -0700 (PDT) Date: Wed, 17 Jul 2019 15:23:39 -0700 In-Reply-To: <20190717222340.137578-1-saravanak@google.com> Message-Id: <20190717222340.137578-5-saravanak@google.com> Mime-Version: 1.0 References: <20190717222340.137578-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [PATCH v3 4/5] PM / devfreq: Cache OPP table reference in devfreq From: Saravana Kannan To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Saravana Kannan , Sibi Sankar , kernel-team@android.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org 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 The OPP table can be used often in devfreq. Trying to get it each time can be expensive, so cache it in the devfreq struct. Signed-off-by: Saravana Kannan Reviewed-by: Chanwoo Choi Acked-by: MyungJoo Ham --- drivers/devfreq/devfreq.c | 6 ++++++ include/linux/devfreq.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 784c08e4f931..7984b01d585d 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -594,6 +594,8 @@ static void devfreq_dev_release(struct device *dev) if (devfreq->profile->exit) devfreq->profile->exit(devfreq->dev.parent); + if (devfreq->opp_table) + dev_pm_opp_put_opp_table(devfreq->opp_table); mutex_destroy(&devfreq->lock); kfree(devfreq); } @@ -674,6 +676,10 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->max_freq = devfreq->scaling_max_freq; devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev); + devfreq->opp_table = dev_pm_opp_get_opp_table(dev); + if (IS_ERR(devfreq->opp_table)) + devfreq->opp_table = NULL; + atomic_set(&devfreq->suspend_count, 0); dev_set_name(&devfreq->dev, "devfreq%d", diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index 2bae9ed3c783..1c05129f76c0 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -116,6 +116,7 @@ struct devfreq_dev_profile { * @profile: device-specific devfreq profile * @governor: method how to choose frequency based on the usage. * @governor_name: devfreq governor name for use with this devfreq + * @opp_table: Reference to OPP table of dev.parent, if one exists. * @nb: notifier block used to notify devfreq object that it should * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. @@ -153,6 +154,7 @@ struct devfreq { struct devfreq_dev_profile *profile; const struct devfreq_governor *governor; char governor_name[DEVFREQ_NAME_LEN]; + struct opp_table *opp_table; struct notifier_block nb; struct delayed_work work; From patchwork Wed Jul 17 22:23:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11048281 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 83FBC6C5 for ; Wed, 17 Jul 2019 22:24:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 74A9D212BE for ; Wed, 17 Jul 2019 22:24:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6864A2877F; Wed, 17 Jul 2019 22:24:11 +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=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham 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 14363212BE for ; Wed, 17 Jul 2019 22:24:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730979AbfGQWYK (ORCPT ); Wed, 17 Jul 2019 18:24:10 -0400 Received: from mail-vk1-f201.google.com ([209.85.221.201]:38629 "EHLO mail-vk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730912AbfGQWYH (ORCPT ); Wed, 17 Jul 2019 18:24:07 -0400 Received: by mail-vk1-f201.google.com with SMTP id u202so11850574vku.5 for ; Wed, 17 Jul 2019 15:24:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=DiFJ3QV0jm1YQeH6o85iwOHAT3O/cgKmhpXPhBt1zRY=; b=gUnX3uWKzKk0PdpWQOACtbCTUosGhC+9X0hmQ8V9U0YJgXRqIB7VQ82FCFG0UaJZgc ANHsa7Am/jr3H95GksDN+aZmOygrs8L74TDbC8/XgptqkBFsTMsk6GligRGiGe/KnInP EDr4mxKVQAhQcthiTTFSxY0rADMAj9jGZYOVzO2PbcLzkZNoEvYe9g0z5YqmuKJ89dF3 B4ByPzdiT6Yhd+AWM6x8lr87ib5BFJAatlvOE+TvhbUy1qN12S/0oJE91nD/HkU6v/JH KT24Fj55t1N5sXs0DGIBl8CjLkb4WmGcxMtiCWEMcGYeR+kD2kDk3oqQVNP3YLiLa6aq sBng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=DiFJ3QV0jm1YQeH6o85iwOHAT3O/cgKmhpXPhBt1zRY=; b=iDPtLX8mJ5On4l19NlPDG4ancg9M4JXIpSgoi87iaAMmLhbSXestVu1+e33XkL8FQJ 5QEHLX5d8O8q706Jvst3079Wl4GiO4OTRjjwdCI7YsN0i83NmqXYiA90Cb8gscSRwwq7 8IlaHvnIiXMMktxcGBntKRiUytiHHpU0lyniSq3QIZL1LMCySq0WDmJpHYnccFOWx+VD yQC+jRE0kN8ZoO0c4CCtZBX/xP5bOnn6Y4IjgVNWByavqMBuULfEI7euX/lEoo8gljqb 8082BZjwH3ti6MQSHipTPo4yLnv6krELo6Ap/35CYMjDSV/l2MwErIbwH1WFyiRK83rc jJnw== X-Gm-Message-State: APjAAAWW01DwMJ5vi3lmm1L+ek4XBsvyJ91oG29io00eOBVIMmP7rnmO NGo2UmS3f1LuKBHij4kv6yCV22kk8hWKh9Q= X-Google-Smtp-Source: APXvYqy3zbgHJTqW4oLLmWuWgsYaMIERwR4ozjSI+WlW5wAorsi4CAIdlvBrgoJK7UM67//EQe4dWRuDxbj9++c= X-Received: by 2002:ab0:7457:: with SMTP id p23mr4958003uaq.138.1563402246655; Wed, 17 Jul 2019 15:24:06 -0700 (PDT) Date: Wed, 17 Jul 2019 15:23:40 -0700 In-Reply-To: <20190717222340.137578-1-saravanak@google.com> Message-Id: <20190717222340.137578-6-saravanak@google.com> Mime-Version: 1.0 References: <20190717222340.137578-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog Subject: [PATCH v3 5/5] PM / devfreq: Add required OPPs support to passive governor From: Saravana Kannan To: MyungJoo Ham , Kyungmin Park , Chanwoo Choi , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Saravana Kannan , Sibi Sankar , kernel-team@android.com, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org 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 Look at the required OPPs of the "parent" device to determine the OPP that is required from the slave device managed by the passive governor. This allows having mappings between a parent device and a slave device even when they don't have the same number of OPPs. Signed-off-by: Saravana Kannan Acked-by: MyungJoo Ham Acked-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 58308948b863..24ce94c80f06 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -19,7 +19,7 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, = (struct devfreq_passive_data *)devfreq->data; struct devfreq *parent_devfreq = (struct devfreq *)p_data->parent; unsigned long child_freq = ULONG_MAX; - struct dev_pm_opp *opp; + struct dev_pm_opp *opp = NULL, *p_opp = NULL; int i, count, ret = 0; /* @@ -56,13 +56,20 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, * list of parent device. Because in this case, *freq is temporary * value which is decided by ondemand governor. */ - opp = devfreq_recommended_opp(parent_devfreq->dev.parent, freq, 0); - if (IS_ERR(opp)) { - ret = PTR_ERR(opp); + p_opp = devfreq_recommended_opp(parent_devfreq->dev.parent, freq, 0); + if (IS_ERR(p_opp)) { + ret = PTR_ERR(p_opp); goto out; } - dev_pm_opp_put(opp); + if (devfreq->opp_table && parent_devfreq->opp_table) + opp = dev_pm_opp_xlate_opp(parent_devfreq->opp_table, + devfreq->opp_table, p_opp); + if (opp) { + *freq = dev_pm_opp_get_freq(opp); + dev_pm_opp_put(opp); + goto out; + } /* * Get the OPP table's index of decided freqeuncy by governor @@ -89,6 +96,9 @@ static int devfreq_passive_get_target_freq(struct devfreq *devfreq, *freq = child_freq; out: + if (!IS_ERR_OR_NULL(opp)) + dev_pm_opp_put(p_opp); + return ret; }