From patchwork Wed Jul 24 01:42:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11055503 X-Patchwork-Delegate: viresh.linux@gmail.com 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 C9DBB13A4 for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB4A8286B5 for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AF93A286E0; Wed, 24 Jul 2019 01:42:39 +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 58BD6286B5 for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728490AbfGXBmb (ORCPT ); Tue, 23 Jul 2019 21:42:31 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:47337 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726183AbfGXBma (ORCPT ); Tue, 23 Jul 2019 21:42:30 -0400 Received: by mail-pl1-f202.google.com with SMTP id j12so23073050pll.14 for ; Tue, 23 Jul 2019 18:42:30 -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=vXNliUMoL+aTyYjmgAfXHEWaeVBL//kUql7DwnW99Io=; b=TQyP8wM5LBSf+xD8urLumC9WYG3t8lQgn1LkYsM04Wptn7xQMX5zYiuJw16QwCh+Kh kRWaudqqkrFuGsI+udvANDDtFR3plqgBGPGH1O/KnDmCanVwoLPdLUEKMi6R/+0XCMX2 mfACw0vXNduzaZ5xbLfD0m6e8d7irEbR18s+tTDH5p/WFXhqzunLI/bYZ1uB2TY27lpy ptoMsdSGrPe/V80K4JI+Uo/dmIMoemMCN5Ue+jzbCC9zLOeOw0yEXhNxrhX8HRLyBaAR vNORbSjejJ3WILMX9Zp86bk5qADkwCPMp5hTUwBlyj16vocyn+5ygHhSqudx6sjQJhHo 3qYA== 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=vXNliUMoL+aTyYjmgAfXHEWaeVBL//kUql7DwnW99Io=; b=Ga3aFAD4CbN2n7fNkTmy8N5TZKlvJ8cUDXQBlEzDR+KUM4KY9Bgesqjx5jcldGbj0Y lte9y8GIJ5duCZkndJD1QVjt+ByVdFwVVdMwZGw0MpTmxzmKXgXB1j/rJSvMuCTUbzDf S9Iz9rATtMy1mX7RUWoPmdQaYBL1R1dpr+W3qOSV4HjIn0JNiEAyh2reHNh4JiK31btW qSSG+80SPkzFhI/BddPz+WOIiLut+tXUbmenFp4r2juKC7ma7o8FZOpRa+jcsWEzB2Ci 1DPt6hadnf6/BnkvFL69Q1Whz6M1p5ZrJZrpqGb0WsCkZ03tLLa2TkpN0ZrM0iI02cWg jpwQ== X-Gm-Message-State: APjAAAUJDxSFzjg5B6ohFNwKmzvrWqBwHMKK7EqpwHiFk9DqtiIxPmAx eFc1D35qyu6pl62jo/6JGIr/lGEI9X4Kd+0= X-Google-Smtp-Source: APXvYqxFVrPokl3G/8hclEsKHvyfxZWl8jfKlkacsPygXvPGCv2kbbdjIyqnY6FypqtZ01y48+WLz6HQPEJweQk= X-Received: by 2002:a63:394:: with SMTP id 142mr4772310pgd.43.1563932549513; Tue, 23 Jul 2019 18:42:29 -0700 (PDT) Date: Tue, 23 Jul 2019 18:42:17 -0700 In-Reply-To: <20190724014222.110767-1-saravanak@google.com> Message-Id: <20190724014222.110767-2-saravanak@google.com> Mime-Version: 1.0 References: <20190724014222.110767-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v4 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 24 01:42:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11055501 X-Patchwork-Delegate: viresh.linux@gmail.com 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 234C5138D for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10635286B5 for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F3FA5286E0; Wed, 24 Jul 2019 01:42:38 +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 7E8E3286B5 for ; Wed, 24 Jul 2019 01:42:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728507AbfGXBme (ORCPT ); Tue, 23 Jul 2019 21:42:34 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:49348 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728374AbfGXBmd (ORCPT ); Tue, 23 Jul 2019 21:42:33 -0400 Received: by mail-pf1-f201.google.com with SMTP id 145so27442409pfw.16 for ; Tue, 23 Jul 2019 18:42:33 -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=AlLsqq3JZoQR71QbtZw0BssW/4/b+9WusH3P4c2zA1g=; b=tmIxXRh1CzRVBErDXUtwQUib7z0gyuxbrGT4Dumdpo/LNx5ctaIziALV0oC5vyzdtF ZUYLE5BllTzxVwqOtyxmp+aCGIuKR9GKgEcLfh3ezGCjqa0xrWQhkYvklb52TNMP3ymN b/QcJ2/GaLDuhNFs05zgY8kY79sLDbc03HH1VBFrUUdioOpiYx5Ag3hK9kY2tw4pm8Gs Ez/G9GLiHLQpuuq/Fx+CG2OEGbld5166zf6hvstPbj1zy4/2Ggtsvg5hXMCmmvl85nd6 SWk51mt+f4FMxt7HoYCOLW/F9MPvzK1XhJ+9xjKjria5kw2+4iy0O9KmAAYi4z6vZCA4 UYfg== 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=AlLsqq3JZoQR71QbtZw0BssW/4/b+9WusH3P4c2zA1g=; b=I7H+XvQpbdy6Ll253pnwREcl4a4H47TS6Et7MyZuGJAPVMA3T2DbDGVHoyKZJ/96Jt wdfCjB4qdvIWisr16/n5ja1XP/OWyc3APHGPahTJpbJcZL+Wrp+DnzRZVsKtIeDYcJwj t+ZoR+P0vb15+XMLYIigR9UAJVN4JdqFPattZGTyC/kSQKpQrrcDPXRAJD95wys+d7EW AeHtLZMmfCsyr3byNcBz3kxnIrNfZSO0IJbFoUXEuv+wu8Nt3UgAGd7gXdla7pwN4P4U fqd4CGgsNXr8aYxwalDLfFl6xYuomYZOIxjR+jWTlXuTQjpLm/Tu0U+mkMnt4r1e5Cia +DzQ== X-Gm-Message-State: APjAAAX5QefIiKlhuEpFBD6p4UOIUWDo7w7VGBagmceko9jtjp7Tvz8h +zQoWkAc8WszTDyZWNKPbyFmlZfB0hTvB9Q= X-Google-Smtp-Source: APXvYqzkaFKYh5Ik7ceQ1KGE0Fun2/u+dwQaWFzR63gtTpqlU+7qAEOGUQV3Nw0gt36cj5Mvk0/G9fNaDXazOnM= X-Received: by 2002:a65:49cc:: with SMTP id t12mr73912466pgs.83.1563932552371; Tue, 23 Jul 2019 18:42:32 -0700 (PDT) Date: Tue, 23 Jul 2019 18:42:18 -0700 In-Reply-To: <20190724014222.110767-1-saravanak@google.com> Message-Id: <20190724014222.110767-3-saravanak@google.com> Mime-Version: 1.0 References: <20190724014222.110767-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v4 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 | 53 ++++++++++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 11 +++++++++ 2 files changed, 64 insertions(+) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 438fcd134d93..5460b7da110e 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1883,6 +1883,59 @@ void dev_pm_opp_detach_genpd(struct opp_table *opp_table) } EXPORT_SYMBOL_GPL(dev_pm_opp_detach_genpd); +/** + * dev_pm_opp_xlate_required_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. + * + * 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_required_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..21d331de98b9 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -130,6 +130,9 @@ struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*s 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); +struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, + struct opp_table *dst_table, + struct dev_pm_opp *src_opp); int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate); 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); @@ -299,6 +302,14 @@ static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, cons static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {} +static inline struct dev_pm_opp *dev_pm_opp_xlate_required_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_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate) { return -ENOTSUPP; From patchwork Wed Jul 24 01:42:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11055505 X-Patchwork-Delegate: viresh.linux@gmail.com 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 A9BFF13A4 for ; Wed, 24 Jul 2019 01:42:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9993A286B5 for ; Wed, 24 Jul 2019 01:42:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8DD20286E0; Wed, 24 Jul 2019 01:42:40 +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 CB8DD286B8 for ; Wed, 24 Jul 2019 01:42:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728526AbfGXBmi (ORCPT ); Tue, 23 Jul 2019 21:42:38 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:55365 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728522AbfGXBmh (ORCPT ); Tue, 23 Jul 2019 21:42:37 -0400 Received: by mail-pf1-f202.google.com with SMTP id i26so27374878pfo.22 for ; Tue, 23 Jul 2019 18:42:36 -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=SEZs2jCYZVWtwNC2TIXQwixIlhahYNp/FR94S5BAgLI=; b=GLzeC8O2RxI0vi+5KBEE/tj5Pt9sRQLtQpwXGEaiVTr3ksjh9xyVh0hkvPXlX6ghHD LY892stmN/RwLry2XliiTDP72x05E9GeA7Ekd3YRz9qyOx0Gj6EiRMt/r6eHhMHkLTRu HDePkjuNqOMo5HK82ePKcn0UjaUkTiXcDKXBgSCENMQ/scKEF6fRWfWYCgcfxSNVAyMb 4+8VwxE2OxutYYs68sJliGL+ZnwiMBa0ObCoTY6mqSxwTRxpds2dXSicjJTGSzm8tO8e jv6nGP+acXMj1JE1h7mjBkFPr2KTds0aAduOscYxCANeN5e0A0FwVbod6jWFJM/FuaMd yniA== 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=SEZs2jCYZVWtwNC2TIXQwixIlhahYNp/FR94S5BAgLI=; b=c2QQgKWXR73yB15jJakvRxdfraQc95AodX57DuUQ5IRzSHfMGOWEQQbYrs5OZYouBu yGXUMPIeen5gbelb+gIDmH7NnY/iwm4HBJF9y3hqEL0Q8IiGPtk/6KPdqHHGIe/wBvLB sr/t6nkjOv+XUFmrDGoz0NyXcmDprgl9Sgl58DPy/exf2UjYa6syNs29LP0OZTyENVhG g8G2frLeNAk173BOuv9nv8OWfYL6pTFhMruxC/+12ikO2zmKI/Ct/alb8X3++a3Oz3wX v3mvaPCJArm3rUxTexvAHWhD5Qv5q2FHpd07lJLHJ3QVPAy1jQNGxgHu4U25CxQosooi h5nw== X-Gm-Message-State: APjAAAUkdXP+HwNdhh8YYZfy2A3X4yZqopjjkBAaE1uCtuY8+nq3gk8x tPGEwUwQWEL/9NajuXtxknqbAQGAHivFpNQ= X-Google-Smtp-Source: APXvYqx4miufCPfOh/OX7LGdgKZNTHriSMVQIat7T8l+We+el8Wt8FvO5jww/CDSgEBmVa0tGfpT+475WuM2aMU= X-Received: by 2002:a63:20a:: with SMTP id 10mr78418083pgc.226.1563932555775; Tue, 23 Jul 2019 18:42:35 -0700 (PDT) Date: Tue, 23 Jul 2019 18:42:19 -0700 In-Reply-To: <20190724014222.110767-1-saravanak@google.com> Message-Id: <20190724014222.110767-4-saravanak@google.com> Mime-Version: 1.0 References: <20190724014222.110767-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v4 3/5] OPP: Improve required-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 --- drivers/opp/core.c | 30 ++++++++++---- drivers/opp/of.c | 101 ++++++++++++++++++++++++--------------------- drivers/opp/opp.h | 5 +++ 3 files changed, 80 insertions(+), 56 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 5460b7da110e..01c71d145ec7 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -706,6 +706,9 @@ static int _set_required_opps(struct device *dev, if (!required_opp_tables) return 0; + if (!_of_lazy_link_required_tables(opp_table)) + return -EPROBE_DEFER; + /* Single genpd case */ if (!genpd_virt_devs && required_opp_tables[0]->is_genpd) { pstate = likely(opp) ? opp->required_opps[0]->pstate : 0; @@ -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", @@ -1906,8 +1914,11 @@ struct dev_pm_opp *dev_pm_opp_xlate_required_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; } @@ -1970,6 +1981,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; @@ -1985,15 +1998,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..1f2860b2d6e5 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,65 @@ 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; +} + +/* + * Try to link all required tables and return true if all of them have been + * linked. Otherwise, return false. + */ +bool _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, num_linked = 0; - for (i = 0; i < count; i++) { - required_np = of_parse_required_opp(np, i); - if (!required_np) - goto free_required_tables; + mutex_lock(&src->lock); - required_opp_tables[i] = _find_table_of_opp_np(required_np); - of_node_put(required_np); + if (list_empty(&src->opp_list)) + goto out; - if (IS_ERR(required_opp_tables[i])) - goto free_required_tables; - } + src_opp = list_first_entry(&src->opp_list, struct dev_pm_opp, node); - goto put_np; + for (i = 0; i < src->required_opp_count; i++) { + if (src->required_opp_tables[i]) { + num_linked++; + continue; + } -free_required_tables: - _opp_table_free_required_tables(opp_table); -put_np: - of_node_put(np); + 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); + } + num_linked++; + } + +out: + mutex_unlock(&src->lock); + return num_linked == src->required_opp_count; } void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, @@ -267,7 +297,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 +312,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 +323,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, @@ -687,6 +690,8 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) if (pstate_count) opp_table->genpd_performance_state = true; + _of_lazy_link_required_tables(opp_table); + opp_table->parsed_static_opps = true; return 0; diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 01a500e2c40a..77e8394fd0fe 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -223,12 +223,17 @@ void _put_opp_list_kref(struct opp_table *opp_table); void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index); void _of_clear_opp_table(struct opp_table *opp_table); struct opp_table *_managed_opp(struct device *dev, int index); +bool _of_lazy_link_required_tables(struct opp_table *src); void _of_opp_free_required_opps(struct opp_table *opp_table, struct dev_pm_opp *opp); #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; } +bool _of_lazy_link_required_tables(struct opp_table *src) +{ + return true; +} static inline void _of_opp_free_required_opps(struct opp_table *opp_table, struct dev_pm_opp *opp) {} #endif From patchwork Wed Jul 24 01:42:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11055509 X-Patchwork-Delegate: viresh.linux@gmail.com 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 A46CA13A4 for ; Wed, 24 Jul 2019 01:42:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 95E79286E0 for ; Wed, 24 Jul 2019 01:42:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 89B8628779; Wed, 24 Jul 2019 01:42:54 +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 2C4FD286B5 for ; Wed, 24 Jul 2019 01:42:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728550AbfGXBmx (ORCPT ); Tue, 23 Jul 2019 21:42:53 -0400 Received: from mail-qt1-f202.google.com ([209.85.160.202]:39392 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728528AbfGXBmk (ORCPT ); Tue, 23 Jul 2019 21:42:40 -0400 Received: by mail-qt1-f202.google.com with SMTP id o16so40013062qtj.6 for ; Tue, 23 Jul 2019 18:42:39 -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=UHmTiaufl6SZU/ga2qxE1n4DzY+HliCfb2daW2FDx5s=; b=F/pbGCP0Z49OtouWOpJ4H0DXRkAubfHQGcLlqlsa5NDb1CDAnuVsUAS5VFQQsxYucW KyDGrT8U88EZ5h6RYqhpaXu02TZd5awobBVJ03rNjXLWPAFIwY0Jh03vzCSeEo8+Vp0s nTFk0UFa25oagNxikNPB7ilbcW8AMRiHf/5HP5Nlmf5hpunxS9FLqNomJ9mCCf1gbFj8 JFQNkTADaNu1PRNErHMMQc7JOn31bz6jNpJrT+0nM+orWutTK/+vx3qps8/8avzwTxJb NGFYHgaL/bfKfOJQGK7+nxvNaQQwWawlLsP1W1Auqee0R/z1ftoTMCPibotRnNtqw1om ayfw== 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=UHmTiaufl6SZU/ga2qxE1n4DzY+HliCfb2daW2FDx5s=; b=JMrZilSSYtyulPUHNPnQmwChbiIRMHnVSwfh4ghjrIeUMRlLdZ3vDShu2nzQxnP1Ug VlT36/WSJE++BLTEl2SjoxrKtXzvcAW8T15oqYW++KogmNmF8+qztTryMzQkVTqfCb1d TcZIA9UFTTNeiNHpMa0cRw3OpvliPLq0Rl4Efk8wAS1EWmIiLJouK0Gv5uQyMUOIhgC6 kxG/+tSm124vrwDjAVa+vOuReXQ+WT8Qf26b/u3zwRMQo89i7IqMoq34TlZPyOwey6cI MehMlSlcLKlY9ffjKHBeot712d5evyzcBxUxGYczBIfy1NFjKGLQHBogGjQ8rea0U2jh W1hg== X-Gm-Message-State: APjAAAWvNQpUej3rrhSDsIk0/3YVqWd0F48D4pDgPNd4cb2uFaYccdS1 o0Pmt+PKyd2WWaIMiqHyhllAcujFdK0yZHs= X-Google-Smtp-Source: APXvYqxss61/VE7v9dgtMgGjjEpT3s/T/+xiumelI1+T+A9k+d2XukhCv5scQKRkHMyYQl8CFsCDwovwd8/r4WQ= X-Received: by 2002:ac8:3345:: with SMTP id u5mr55871060qta.219.1563932558973; Tue, 23 Jul 2019 18:42:38 -0700 (PDT) Date: Tue, 23 Jul 2019 18:42:20 -0700 In-Reply-To: <20190724014222.110767-1-saravanak@google.com> Message-Id: <20190724014222.110767-5-saravanak@google.com> Mime-Version: 1.0 References: <20190724014222.110767-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v4 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 24 01:42:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saravana Kannan X-Patchwork-Id: 11055507 X-Patchwork-Delegate: viresh.linux@gmail.com 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 A88AB138D for ; Wed, 24 Jul 2019 01:42:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 981AD286B5 for ; Wed, 24 Jul 2019 01:42:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C275286E0; Wed, 24 Jul 2019 01: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=-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 09FFE286B5 for ; Wed, 24 Jul 2019 01:42:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728523AbfGXBmp (ORCPT ); Tue, 23 Jul 2019 21:42:45 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:41844 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728552AbfGXBmn (ORCPT ); Tue, 23 Jul 2019 21:42:43 -0400 Received: by mail-pf1-f202.google.com with SMTP id q14so27463295pff.8 for ; Tue, 23 Jul 2019 18:42:42 -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=tcec6G8mdYvC44AUiiZquxcEHQD3/poU4Cd0DIagRzY=; b=OjqB0ijOd5pzNZ1elvcBfW/VYQq9Xyi191z3lVRIEijGecmCpThtCaH7iAEAOQV6tt n1Ma7p9sAXcFTkGiDuRpVzqQGS9v541NtuMY6wTBEFaB3+mr4IX8M4w8OiWHQCvmubm8 Yju7NLSi4U7n/lTTOksPbc2XETeb5BvCiu5vo6wve7xyJW1gy/VAecz2XFeG0rLFAV/G zZ+mJdKhPjpQMlhvl95+iF1kVbre+8PnJY5WGzv4zkJmDfzAx29ovEXNLLGStTbDkEc+ NJ0im1qi8CZTIkUMjx+pxaVVsobC496FzzkLJtNZgBvfbrzOAV7JFut85IszWRP7WF0K 9S+w== 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=tcec6G8mdYvC44AUiiZquxcEHQD3/poU4Cd0DIagRzY=; b=jHIR2G20Ac2oKK5uEP1S9dIc/P68tUI7akwSwuMvQWag04tjk2Vc00LGHzQLhI6lCM BplqZg5Inzm3/AX4TX1T8kX6AeY7edvE/84NEoVwuZBq8EnJaJ6xscMSW1UoIZ5gZd6W hJk3ouvyKqEos53OtwlkHnbsCLm8B/sf8/Ovf04Tnlv5Wv8KmfyxOEHhjwdSy2RhdEhj vUiHPjxPyQtvrT/TidWuBMZkGNLmlmdSPP0di8sz8QzKpkAGNjgIHybaULbNZPbbrF/Q adis+xazaj1q6Cw0y/TA4HcTAkllyOIB0FYKmRKhp4Y8tLkE8bjIR2eMLuN6DWwnc6UR 29Aw== X-Gm-Message-State: APjAAAXxL8M5jnPUu4TMGF6otrvjmeRvy+3g68yJKXIYwH2lFCrOEnRd atg+Z1PL96Qh7R3PaEN/xX8vtPhOXY9A/4s= X-Google-Smtp-Source: APXvYqzFshsuv+IyMmfv+K7ZxtUfZm5PhJHbRo0sv/PZ+9kPjXaRXrDQoTPve3lpQ+P63v+BW0L/MbdyD6oDveA= X-Received: by 2002:a63:4404:: with SMTP id r4mr77919539pga.245.1563932561833; Tue, 23 Jul 2019 18:42:41 -0700 (PDT) Date: Tue, 23 Jul 2019 18:42:21 -0700 In-Reply-To: <20190724014222.110767-1-saravanak@google.com> Message-Id: <20190724014222.110767-6-saravanak@google.com> Mime-Version: 1.0 References: <20190724014222.110767-1-saravanak@google.com> X-Mailer: git-send-email 2.22.0.709.g102302147b-goog Subject: [PATCH v4 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..14dc5bb58733 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_required_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; }