From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69FC3C43334 for ; Fri, 10 Jun 2022 08:24:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244556AbiFJIYa (ORCPT ); Fri, 10 Jun 2022 04:24:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347445AbiFJIYL (ORCPT ); Fri, 10 Jun 2022 04:24:11 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 083EE3E866F for ; Fri, 10 Jun 2022 01:21:07 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id cx11so23453980pjb.1 for ; Fri, 10 Jun 2022 01:21:07 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=nqmtsnnn/rBbgkYjsLkZHJ0d80G5x0xgJus9h30FBZI=; b=RWzCHuEdf3vWCLjvt9cbjQmgL5DJ8D41Dw0K9q7oQ2Z17dJVX/Ex8GYjo4MxpIMyIx n1jHM8GfK7Rjl8yTKYpta3YOhk7wz+q/3mebsqtJDiDlbo03fegZXHY6nW0czkAajCrI NKoHem/WfBBDFKBvkOTszVml4Vw/Bak1nDSP6p/4mw041gKK4f6gt8cRnU918RztLxor xx3bJG0/ZeLhNkaQKrorpXipGhF5IWQogb+mCuP8JieCIVsYUt3LAuWb/fzDxgMA0WUD OUy/iDZ67NpeGVRqO3pSxWH/WabsZSP84xmnl/3eIVdEu5h6553DgmmiHX6H3ZPXjGby glyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nqmtsnnn/rBbgkYjsLkZHJ0d80G5x0xgJus9h30FBZI=; b=4MEu+VDQVhJLu3D6AspHjF3z+te9KxjZfbSZFCYiOSeLcCNMQr9FCd6nlFtaskSArX gcrSt08mGw5l9IjV6Oi3VN72BVdB2R5XqZGEv9g3vcCqLN7E1zMW69B0rToUbD5rIXTb s3dEjqpcKZk+vdSc1YG+HZcH3CbYA5RsMkIqnHKgqpo/qnQIZnC/D4+/f9fqjy/phjJN Jt2fIU+uJTq9Jzb//0jjGXzzw061ktI70YzmdM8YsbOS1qZ33fPj6hAAFNwyYSBQfm4G dUPJvb+S65MIgoE7M3FK+X5OvdI2bMiOdQJi7NP3SPWfyc6ap3/JB/ZuH9xFTxkn8eNO 3U4g== X-Gm-Message-State: AOAM532+5lGxmRcvUIAt4Mh3ivxVkLMWH/AIeH6ACjndWyqmXrqFb+53 K9yF6Z3TwCdOjkcHf2lfTL9zUA== X-Google-Smtp-Source: ABdhPJzyphAF7MDKdO4LsySNr5NaWrcjnl2906vaS5KqAf4pmbtKPZggcXN/K3cTSGASmWxsAIJbvw== X-Received: by 2002:a17:90b:350b:b0:1e8:5177:fe7d with SMTP id ls11-20020a17090b350b00b001e85177fe7dmr7789962pjb.142.1654849266751; Fri, 10 Jun 2022 01:21:06 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id n10-20020a056a0007ca00b0051bd9981ccbsm15298810pfu.39.2022.06.10.01.21.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:06 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 1/8] OPP: Use consistent names for OPP table instances Date: Fri, 10 Jun 2022 13:50:45 +0530 Message-Id: <03780196cbd07ffff8ea4a1b2b4627a19a22e262.1654849214.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The OPP table is called "opp_table" at most of the places and "table" at few. Make all of them follow the same naming convention, "opp_table". Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 7 ++++--- drivers/opp/cpu.c | 12 ++++++------ drivers/opp/of.c | 12 ++++++------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 6e6c1ca92641..404f43759066 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1567,15 +1567,16 @@ void dev_pm_opp_remove_all_dynamic(struct device *d= ev) } EXPORT_SYMBOL_GPL(dev_pm_opp_remove_all_dynamic); =20 -struct dev_pm_opp *_opp_allocate(struct opp_table *table) +struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table) { struct dev_pm_opp *opp; int supply_count, supply_size, icc_size; =20 /* Allocate space for at least one supply */ - supply_count =3D table->regulator_count > 0 ? table->regulator_count : 1; + supply_count =3D opp_table->regulator_count > 0 ? + opp_table->regulator_count : 1; supply_size =3D sizeof(*opp->supplies) * supply_count; - icc_size =3D sizeof(*opp->bandwidth) * table->path_count; + icc_size =3D sizeof(*opp->bandwidth) * opp_table->path_count; =20 /* allocate new OPP node and supplies structures */ opp =3D kzalloc(sizeof(*opp) + supply_size + icc_size, GFP_KERNEL); diff --git a/drivers/opp/cpu.c b/drivers/opp/cpu.c index 5004335cf0de..3c3506021501 100644 --- a/drivers/opp/cpu.c +++ b/drivers/opp/cpu.c @@ -41,7 +41,7 @@ * the table if any of the mentioned functions have been invoked in the in= terim. */ int dev_pm_opp_init_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table) + struct cpufreq_frequency_table **opp_table) { struct dev_pm_opp *opp; struct cpufreq_frequency_table *freq_table =3D NULL; @@ -76,7 +76,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, freq_table[i].driver_data =3D i; freq_table[i].frequency =3D CPUFREQ_TABLE_END; =20 - *table =3D &freq_table[0]; + *opp_table =3D &freq_table[0]; =20 out: if (ret) @@ -94,13 +94,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_init_cpufreq_table); * Free up the table allocated by dev_pm_opp_init_cpufreq_table */ void dev_pm_opp_free_cpufreq_table(struct device *dev, - struct cpufreq_frequency_table **table) + struct cpufreq_frequency_table **opp_table) { - if (!table) + if (!opp_table) return; =20 - kfree(*table); - *table =3D NULL; + kfree(*opp_table); + *opp_table =3D NULL; } EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table); #endif /* CONFIG_CPU_FREQ */ diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 30394929d700..e07fc31de416 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -767,7 +767,7 @@ void dev_pm_opp_of_remove_table(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); =20 -static int _read_bw(struct dev_pm_opp *new_opp, struct opp_table *table, +static int _read_bw(struct dev_pm_opp *new_opp, struct opp_table *opp_tabl= e, struct device_node *np, bool peak) { const char *name =3D peak ? "opp-peak-kBps" : "opp-avg-kBps"; @@ -780,9 +780,9 @@ static int _read_bw(struct dev_pm_opp *new_opp, struct = opp_table *table, return -ENODEV; =20 count =3D prop->length / sizeof(u32); - if (table->path_count !=3D count) { + if (opp_table->path_count !=3D count) { pr_err("%s: Mismatch between %s and paths (%d %d)\n", - __func__, name, count, table->path_count); + __func__, name, count, opp_table->path_count); return -EINVAL; } =20 @@ -808,7 +808,7 @@ static int _read_bw(struct dev_pm_opp *new_opp, struct = opp_table *table, return ret; } =20 -static int _read_opp_key(struct dev_pm_opp *new_opp, struct opp_table *tab= le, +static int _read_opp_key(struct dev_pm_opp *new_opp, struct opp_table *opp= _table, struct device_node *np, bool *rate_not_available) { bool found =3D false; @@ -832,10 +832,10 @@ static int _read_opp_key(struct dev_pm_opp *new_opp, = struct opp_table *table, * opp-peak-kBps =3D ; * opp-avg-kBps =3D ; */ - ret =3D _read_bw(new_opp, table, np, true); + ret =3D _read_bw(new_opp, opp_table, np, true); if (!ret) { found =3D true; - ret =3D _read_bw(new_opp, table, np, false); + ret =3D _read_bw(new_opp, opp_table, np, false); } =20 /* The properties were found but we failed to parse them */ --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7A85C43334 for ; Fri, 10 Jun 2022 08:24:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347373AbiFJIYp (ORCPT ); Fri, 10 Jun 2022 04:24:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347598AbiFJIYP (ORCPT ); Fri, 10 Jun 2022 04:24:15 -0400 Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C5F573EB9CA for ; Fri, 10 Jun 2022 01:21:10 -0700 (PDT) Received: by mail-pl1-x632.google.com with SMTP id i15so5466126plr.1 for ; Fri, 10 Jun 2022 01:21:10 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=/vcF/QNpvPLcA4RHww4ViDk70wdKPxBVofdBW3sgq5c=; b=p7V4YUibibj9AvSgBH2AE999cHg+ec4xuwtZHf4oCKGnASuR7Jk0TqhUUEF8XaOR+r wxrU+j3QghaV8hAB+Mvm7zWzgiR8PrkF6FJiBDH3G6YzWYJr5ALY7k090vQONfMRnqGz vZyYQPntTUBRfaqBoadikhkcg9ew+Deswu/DB5qzND4R/Re+hF6ZHZO7pRBGchYvuh31 0o8C8nuOLY+O9O1rY1t04DJ55Z74U3IQGI0+lPuUcillbKNVNihZ4TITwbccLshYVfHW 5RjBUvwS6JJEh/6dMcUm+pwOMB1QW/paW/1WuwqRkMabzSMgl2Nbdv3U1GxaUuZ7gb2I hbhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/vcF/QNpvPLcA4RHww4ViDk70wdKPxBVofdBW3sgq5c=; b=BxiPuhZED8yA4Fho3BbXhWC7pSJK758QOnmAy0WoeR43ZjzXZUvzlbyB/r0id25WNw XC74c/9z3ZXJjQjHoL5tSN7YLPAz7Jf2dfj/PUgw8neqUT2/ql3sY+13gI5tDf7vfaJo xwsC9IHzmlax5DVGr4cBGfGFlpyUrGCz2evTqsSp1a2ahHlVc/vuiBfAUux0QbMTLo55 6tGa+DuZjTKu5teH+ZC14tuKMmZX0LssKzc1UmDye093c11MeVPhUJBvtyc6Wb8SpYss MzPk0pWBCr5LFB/PRaFz0rvUAO1xApo99OadPvTYBk7jHhBP9Wxvf7/t/uW+0YjQz9qf RZyQ== X-Gm-Message-State: AOAM533+NOmS99KYgy0mCWXhlgqKkWiMEELVNG1f62hUCkAIoz2RJRdX YiqHqAv0UsYoSXrBb8SNANbZMA== X-Google-Smtp-Source: ABdhPJw7e/wORoEphD60Ma+eCczcirA3YOZoOwIoYuv97QFY+ER1reFifPnoU6cQu5aFzCmqGq8K8w== X-Received: by 2002:a17:90b:368b:b0:1e6:67a0:1c17 with SMTP id mj11-20020a17090b368b00b001e667a01c17mr7494284pjb.203.1654849269662; Fri, 10 Jun 2022 01:21:09 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id w4-20020a17090aaf8400b001e0abbc3a74sm1092638pjq.5.2022.06.10.01.21.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:09 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 2/8] OPP: Remove rate_not_available parameter to _opp_add() Date: Fri, 10 Jun 2022 13:50:46 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" commit 32715be4fe95 ("opp: Fix adding OPP entries in a wrong order if rate is unavailable") removed the only user of this field, get rid of rest of it now. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 4 ++-- drivers/opp/of.c | 10 ++++------ drivers/opp/opp.h | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 404f43759066..fe447f41c99e 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1695,7 +1695,7 @@ void _required_opps_available(struct dev_pm_opp *opp,= int count) * should be considered an error by the callers of _opp_add(). */ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, - struct opp_table *opp_table, bool rate_not_available) + struct opp_table *opp_table) { struct list_head *head; int ret; @@ -1774,7 +1774,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct d= evice *dev, new_opp->available =3D true; new_opp->dynamic =3D dynamic; =20 - ret =3D _opp_add(dev, new_opp, opp_table, false); + ret =3D _opp_add(dev, new_opp, opp_table); if (ret) { /* Don't return error for duplicate OPPs */ if (ret =3D=3D -EBUSY) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index e07fc31de416..bec9644a7260 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -808,8 +808,8 @@ static int _read_bw(struct dev_pm_opp *new_opp, struct = opp_table *opp_table, return ret; } =20 -static int _read_opp_key(struct dev_pm_opp *new_opp, struct opp_table *opp= _table, - struct device_node *np, bool *rate_not_available) +static int _read_opp_key(struct dev_pm_opp *new_opp, + struct opp_table *opp_table, struct device_node *np) { bool found =3D false; u64 rate; @@ -825,7 +825,6 @@ static int _read_opp_key(struct dev_pm_opp *new_opp, st= ruct opp_table *opp_table new_opp->rate =3D (unsigned long)rate; found =3D true; } - *rate_not_available =3D !!ret; =20 /* * Bandwidth consists of peak and average (optional) values: @@ -881,13 +880,12 @@ static struct dev_pm_opp *_opp_add_static_v2(struct o= pp_table *opp_table, struct dev_pm_opp *new_opp; u32 val; int ret; - bool rate_not_available =3D false; =20 new_opp =3D _opp_allocate(opp_table); if (!new_opp) return ERR_PTR(-ENOMEM); =20 - ret =3D _read_opp_key(new_opp, opp_table, np, &rate_not_available); + ret =3D _read_opp_key(new_opp, opp_table, np); if (ret < 0) { dev_err(dev, "%s: opp key field not found\n", __func__); goto free_opp; @@ -920,7 +918,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp= _table *opp_table, if (opp_table->is_genpd) new_opp->pstate =3D pm_genpd_opp_to_performance_state(dev, new_opp); =20 - ret =3D _opp_add(dev, new_opp, opp_table, rate_not_available); + ret =3D _opp_add(dev, new_opp, opp_table); if (ret) { /* Don't return error for duplicate OPPs */ if (ret =3D=3D -EBUSY) diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 407eee9f10ab..4d8894ef2975 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -226,7 +226,7 @@ struct opp_device *_add_opp_dev(const struct device *de= v, struct opp_table *opp_ struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table); void _opp_free(struct dev_pm_opp *opp); int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2); -int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_ta= ble *opp_table, bool rate_not_available); +int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_ta= ble *opp_table); int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned = long freq, long u_volt, bool dynamic); void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int l= ast_cpu); struct opp_table *_add_opp_table_indexed(struct device *dev, int index, bo= ol getclk); --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1390AC43334 for ; Fri, 10 Jun 2022 08:24:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347607AbiFJIYl (ORCPT ); Fri, 10 Jun 2022 04:24:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347523AbiFJIYN (ORCPT ); Fri, 10 Jun 2022 04:24:13 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 137CF3EEE0E for ; Fri, 10 Jun 2022 01:21:13 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id g205so23226499pfb.11 for ; Fri, 10 Jun 2022 01:21:13 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=3J6lXA8/rnBftbG6MsbGJ9PP4BJZM2h2Yta2UTOvcDU=; b=jjcUUEhFvaPSb7bFG49Tbd3Z1VjBlGsuPIlk7NFMhLPoJ8gVI5ZQX8X8bjgIrMhGg7 6svc82XE3Yw+JEyCn8f2tT2WXDtPvjsPh98puFpBr43czhAiWrUEoluUdl3Dh9FS4iH0 UTCtzX6UJ1YucSJfGzK8hlJ1zDfJn5ppylIlBCAGBaVlTAbo4cqfb92/pMIb6pLX0D41 1zXjlLF4gtjEXhU1ppXTRbbe+H9DCREaaFnOgO33lx4fXQhf4oaW3UgAitma87YmDxQd tCqxnA+OxPobKHC+WqX/BihdUXdjlu/rn5z/uiOqC14jV158mDr+kMDQ2UiGd08k1lDd Wmiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3J6lXA8/rnBftbG6MsbGJ9PP4BJZM2h2Yta2UTOvcDU=; b=rtzYgPtjq271TwRXrq2bVTcyqBy6A9gYsE6DHNyo2/nFPF9zjRPrug/bWCEH/tSUs4 5Ua3Zve0Umstj30DEIgat9secArM6xx5LrGUPhtRedHP+Ukb02Fwc7omo5SaX0OaZxQ7 exyQlAC7zhPnl70NKw/D4SdoJVFpCejhCKj/bipTRARW56wOardartIw+HFrFYS1CxAi 2U4G2bCcM90eGlbaZ52/KoFnBNQPH4FQ0MXcUdzz4dbcdVKK5vIII62wnISeYT06FnLG kIb/kZx2PxpZYstQF9ALN17YF3n0QG7PzxhHIFqI1GoFY2JDK1rexib9Hva2XzQ0Yzzb gFuA== X-Gm-Message-State: AOAM531YZDeYuQmpYaja5UGuLO6Iwc8/y7T2qXBI7ERSiXQ/1iGiI9gZ wYpF+e7BV4C7zMIs68AUwyA/fw== X-Google-Smtp-Source: ABdhPJyqTJhOl3tzkF5q8ujg2j82pUcC7YV029PQ0wp9uQlAIZfwG8pfeHWKlanKyHz6+Cyzrx7joA== X-Received: by 2002:a63:4c:0:b0:3fa:b4d8:26cf with SMTP id 73-20020a63004c000000b003fab4d826cfmr37551776pga.463.1654849272507; Fri, 10 Jun 2022 01:21:12 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id u3-20020a17090a5e4300b001e2f892b352sm1080739pji.45.2022.06.10.01.21.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:12 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 3/8] OPP: Reuse _opp_compare_key() in _opp_add_static_v2() Date: Fri, 10 Jun 2022 13:50:47 +0530 Message-Id: <2e335a6c263704a8d465bd02896fc5fff0533fdc.1654849214.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Reuse _opp_compare_key() in _opp_add_static_v2() instead of just comparing frequency while finding suspend frequency. Also add a comment over _opp_compare_key() explaining its return values. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 6 ++++++ drivers/opp/of.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index fe447f41c99e..9f284dc0d9d7 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1618,6 +1618,12 @@ static bool _opp_supported_by_regulators(struct dev_= pm_opp *opp, return true; } =20 +/* + * Returns + * 0: opp1 =3D=3D opp2 + * 1: opp1 > opp2 + * -1: opp1 < opp2 + */ int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2) { if (opp1->rate !=3D opp2->rate) diff --git a/drivers/opp/of.c b/drivers/opp/of.c index bec9644a7260..843923ab9d66 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -929,8 +929,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp= _table *opp_table, /* OPP to select on device suspend */ if (of_property_read_bool(np, "opp-suspend")) { if (opp_table->suspend_opp) { - /* Pick the OPP with higher rate as suspend OPP */ - if (new_opp->rate > opp_table->suspend_opp->rate) { + /* Pick the OPP with higher rate/bw/level as suspend OPP */ + if (_opp_compare_key(opp_table, new_opp, opp_table->suspend_opp) =3D=3D= 1) { opp_table->suspend_opp->suspend =3D false; new_opp->suspend =3D true; opp_table->suspend_opp =3D new_opp; --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8716C43334 for ; Fri, 10 Jun 2022 08:24:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347653AbiFJIYs (ORCPT ); Fri, 10 Jun 2022 04:24:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51290 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347459AbiFJIYR (ORCPT ); Fri, 10 Jun 2022 04:24:17 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 292503F3A6D for ; Fri, 10 Jun 2022 01:21:16 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id k5-20020a17090a404500b001e8875e6242so1474406pjg.5 for ; Fri, 10 Jun 2022 01:21:16 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=Qu+YHy83Y6tmpvXALib3V7ikNYvZhhUbou41agwSzJY=; b=hAaG1te8hUjI0psrNR7K8hfEW9uhSKMW3cOyFinTGEJSgxqPz9AqHOXUQzmRnM2oHp 2dBOjc0rIQnDIkC+bynzLs0drVQLrz++spZIteOP4EOfj+KyttOR2/adAzkBC9TlUi97 WDrbT4EegTlUww461g1+caI39i6qmwbwb3XRVdZHnFAAeie0bS81825KDl6ljxLf6SbN xh5MpokaeGq0r9LFbRe0egtZESOERsIVORsZGihsCcuQ4qsIZxEIMVTTpSlJYcKAenHR jr5Zmxw9E2XrNRA9hHH0Ci/g/AtKxQqHaCWdv8FaAYGm1AVS9foDitVP1/x/VVPUUoI+ mgAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Qu+YHy83Y6tmpvXALib3V7ikNYvZhhUbou41agwSzJY=; b=tfXbEsdYesFozzCXF2Xc/ZTPAlrQOmQUTNGOV7h6hegelO8ZozmAsADlEaj27uf6vG Hpu9IpkyEDZUYaFVKVP03NOQjNQG02AbaKHIDpRJOUaxkv892Nv4MzNWy8P/5RK4FCX0 Jc0rIau01aWwmOGfhIfFpBqWgVxcgBaTFlCEVJZfCJkoz2VHEGDzmgzVnjq9naWj3bkI Hz9RClxPuxxDNp35RW92G96F/Tk7bFir0DuXxBcZAC10Ga6aEsOKIbhPVaCTYSCubHd4 wAlCJOvGmGn3ao2NNVppu0XzcfGMcELachRGJUUHQV9jKHT/1fKJGd+xM6E8CeLM7X5A Hl7Q== X-Gm-Message-State: AOAM533loFw972mvEfh2VsI274UMjQlcRoYY3PZd0U+YxQyFu1F11WWa iR57QG6Pm/jVYCyfFFbQ4QNr2A== X-Google-Smtp-Source: ABdhPJzoW12NwKAawqpIckRDJg0AFfOjbC6Qfj0gkiTdVknPaIvLav11g12rXBp7TE7m2wZ5II9Epg== X-Received: by 2002:a17:90b:3c0b:b0:1ea:769d:4ab2 with SMTP id pb11-20020a17090b3c0b00b001ea769d4ab2mr3570152pjb.196.1654849275588; Fri, 10 Jun 2022 01:21:15 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id l20-20020a170903005400b0015e8d4eb208sm17947276pla.82.2022.06.10.01.21.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:15 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 4/8] OPP: Make dev_pm_opp_set_opp() independent of frequency Date: Fri, 10 Jun 2022 13:50:48 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" dev_pm_opp_set_opp() can be called for any device, it may or may not have a frequency value associated with it. If a frequency value isn't available, we pass 0 to _set_opp(). Make it optional instead by making _set_opp() accept a pointer instead, as the frequency value is anyway available in the OPP. This makes dev_pm_opp_set_opp() and _set_opp() completely independent of any special key value. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 52 +++++++++++++++++++++++++++++++++------------- drivers/opp/opp.h | 4 ++-- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 9f284dc0d9d7..6368ae2d7360 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -766,19 +766,33 @@ static int _set_opp_voltage(struct device *dev, struc= t regulator *reg, return ret; } =20 -static inline int _generic_set_opp_clk_only(struct device *dev, struct clk= *clk, - unsigned long freq) +static inline int _generic_set_opp_clk_only(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data) { + unsigned long *target =3D data; + unsigned long freq; int ret; =20 /* We may reach here for devices which don't change frequency */ - if (IS_ERR(clk)) + if (IS_ERR(opp_table->clk)) return 0; =20 - ret =3D clk_set_rate(clk, freq); + /* One of target and opp must be available */ + if (target) { + freq =3D *target; + } else if (opp) { + freq =3D opp->rate; + } else { + WARN_ON(1); + return -EINVAL; + } + + ret =3D clk_set_rate(opp_table->clk, freq); if (ret) { dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, ret); + } else { + opp_table->rate_clk_single =3D freq; } =20 return ret; @@ -972,7 +986,7 @@ static int _disable_opp_table(struct device *dev, struc= t opp_table *opp_table) } =20 static int _set_opp(struct device *dev, struct opp_table *opp_table, - struct dev_pm_opp *opp, unsigned long freq) + struct dev_pm_opp *opp, void *clk_data, bool forced) { struct dev_pm_opp *old_opp; int scaling_down, ret; @@ -987,15 +1001,14 @@ static int _set_opp(struct device *dev, struct opp_t= able *opp_table, old_opp =3D opp_table->current_opp; =20 /* Return early if nothing to do */ - if (old_opp =3D=3D opp && opp_table->current_rate =3D=3D freq && - opp_table->enabled) { + if (!forced && old_opp =3D=3D opp && opp_table->enabled) { dev_dbg(dev, "%s: OPPs are same, nothing to do\n", __func__); return 0; } =20 dev_dbg(dev, "%s: switching OPP: Freq %lu -> %lu Hz, Level %u -> %u, Bw %= u -> %u\n", - __func__, opp_table->current_rate, freq, old_opp->level, - opp->level, old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0, + __func__, old_opp->rate, opp->rate, old_opp->level, opp->level, + old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0, opp->bandwidth ? opp->bandwidth[0].peak : 0); =20 scaling_down =3D _opp_compare_key(old_opp, opp); @@ -1028,7 +1041,7 @@ static int _set_opp(struct device *dev, struct opp_ta= ble *opp_table, } } =20 - ret =3D _generic_set_opp_clk_only(dev, opp_table->clk, freq); + ret =3D _generic_set_opp_clk_only(dev, opp_table, opp, clk_data); if (ret) return ret; =20 @@ -1064,7 +1077,6 @@ static int _set_opp(struct device *dev, struct opp_ta= ble *opp_table, /* Make sure current_opp doesn't get freed */ dev_pm_opp_get(opp); opp_table->current_opp =3D opp; - opp_table->current_rate =3D freq; =20 return ret; } @@ -1085,6 +1097,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned = long target_freq) struct opp_table *opp_table; unsigned long freq =3D 0, temp_freq; struct dev_pm_opp *opp =3D NULL; + bool forced =3D false; int ret; =20 opp_table =3D _find_opp_table(dev); @@ -1102,7 +1115,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned = long target_freq) * equivalent to a clk_set_rate() */ if (!_get_opp_count(opp_table)) { - ret =3D _generic_set_opp_clk_only(dev, opp_table->clk, target_freq); + ret =3D _generic_set_opp_clk_only(dev, opp_table, NULL, + &target_freq); goto put_opp_table; } =20 @@ -1123,12 +1137,22 @@ int dev_pm_opp_set_rate(struct device *dev, unsigne= d long target_freq) __func__, freq, ret); goto put_opp_table; } + + /* + * An OPP entry specifies the highest frequency at which other + * properties of the OPP entry apply. Even if the new OPP is + * same as the old one, we may still reach here for a different + * value of the frequency. In such a case, do not abort but + * configure the hardware to the desired frequency forcefully. + */ + forced =3D opp_table->rate_clk_single !=3D target_freq; } =20 - ret =3D _set_opp(dev, opp_table, opp, freq); + ret =3D _set_opp(dev, opp_table, opp, &target_freq, forced); =20 if (target_freq) dev_pm_opp_put(opp); + put_opp_table: dev_pm_opp_put_opp_table(opp_table); return ret; @@ -1156,7 +1180,7 @@ int dev_pm_opp_set_opp(struct device *dev, struct dev= _pm_opp *opp) return PTR_ERR(opp_table); } =20 - ret =3D _set_opp(dev, opp_table, opp, opp ? opp->rate : 0); + ret =3D _set_opp(dev, opp_table, opp, NULL, false); dev_pm_opp_put_opp_table(opp_table); =20 return ret; diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 4d8894ef2975..131fc7c05db8 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -138,7 +138,7 @@ enum opp_table_access { * @clock_latency_ns_max: Max clock latency in nanoseconds. * @parsed_static_opps: Count of devices for which OPPs are initialized fr= om DT. * @shared_opp: OPP is shared between multiple devices. - * @current_rate: Currently configured frequency. + * @rate_clk_single: Currently configured frequency for single clk. * @current_opp: Currently configured OPP for the table. * @suspend_opp: Pointer to OPP to be used during device suspend. * @genpd_virt_dev_lock: Mutex protecting the genpd virtual device pointer= s. @@ -187,7 +187,7 @@ struct opp_table { =20 unsigned int parsed_static_opps; enum opp_table_access shared_opp; - unsigned long current_rate; + unsigned long rate_clk_single; struct dev_pm_opp *current_opp; struct dev_pm_opp *suspend_opp; =20 --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4B95C433EF for ; Fri, 10 Jun 2022 08:25:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346356AbiFJIZE (ORCPT ); Fri, 10 Jun 2022 04:25:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55276 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347445AbiFJIYb (ORCPT ); Fri, 10 Jun 2022 04:24:31 -0400 Received: from mail-pj1-x1031.google.com (mail-pj1-x1031.google.com [IPv6:2607:f8b0:4864:20::1031]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 272543F62CD for ; Fri, 10 Jun 2022 01:21:19 -0700 (PDT) Received: by mail-pj1-x1031.google.com with SMTP id a10so23434681pju.3 for ; Fri, 10 Jun 2022 01:21:19 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=5m3c+9x2kGInvjdb6mc3X+Fw5QfrWswpjxX46Et57cA=; b=XRz/RmWb+fcBndD6KlXOk4NoYBP3hk2tGn6jai5qR7CbIdRje/Qcdx85hQv6MlaIVF 3i2a11f6ubSXSz53UgHDMb6dXOETFJObkTSqINMxizdPb01NdOp1vTT0GwfTydwyakdZ 7mOrXzB3vxq8DA8bG1AouUQWQsepuQMLlZvPBHg/1a8xFvUjJsWZUbSQebx2lQo5AC/O Z+ft4e2k/J1jR9l1aOllMC0wWozYrOjJuTbfjlRQtpe4zWt4Jpp0SLHzopCAzlwitIb0 qMyRYUgmk9+6obHlODYZVMZWeur+qfXccgAsXfNjf9grJRutERT5208Zx209VE7Fv5la yscQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5m3c+9x2kGInvjdb6mc3X+Fw5QfrWswpjxX46Et57cA=; b=yOouh0aokltjJQK0dzttNWCGMXBLm//GMGYhwC4NqLNm9NDCEjJ5MNAxn++TxAacJ1 1QpE2glhUQe5ERQqP3imtL9J02T0YvqK7sb9UIfcYwO1j2EThZZW9LhV3jZQBYXG/wPj 62CEZqjHFPIF2RxzAEjRcy2SkCD8jVj7D4HvHODaN6f7SlOeXTJbKqZuTbj1WMzNH3xl okG5hIjk6eLoMNVs2VrbOTZntF8HojJuuV4LynWbn+yeN3Tffba7DIkYS/apCAGTDCQp hYNhlfrPPxLv962QOe9zTcEsYmAMUOhjaVFStFeFIRv+qr0mDyppcJshDAfvR+SOUbdo zpVQ== X-Gm-Message-State: AOAM53101LyWIGrxW8U8avxUu9gAzGYfzDRU8osGq/R/IycKtTPWlp9g JxvePrjBqZDIo6JtoHzt+KyhLA== X-Google-Smtp-Source: ABdhPJxrhUjLXJt6TJhQLsz24mB0kkPdk58TvwaVNGd68v8yvpvaACY9Bsc8zZnuVJmmIaPLAwQHtA== X-Received: by 2002:a17:90b:2246:b0:1e8:5531:5e61 with SMTP id hk6-20020a17090b224600b001e855315e61mr7540883pjb.86.1654849279166; Fri, 10 Jun 2022 01:21:19 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id s12-20020a17090302cc00b0015e8da1fb07sm18118293plk.127.2022.06.10.01.21.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:18 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , linux-kernel@vger.kernel.org Subject: [PATCH 5/8] OPP: Allow multiple clocks for a device Date: Fri, 10 Jun 2022 13:50:49 +0530 Message-Id: <8b29fa207024dc295639f9ba52c28e45782e3baa.1654849214.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch adds support to allow multiple clocks for a device. The design is pretty much similar to how this is done for regulators, and platforms can supply their own version of the config_clks() callback if they have multiple clocks for their device. The core manages the calls via opp_table->config_clks() eventually. We have kept both "clk" and "clks" fields in the OPP table structure and the reason is provided as a comment in _opp_set_clknames(). The same isn't done for "rates" though and we use rates[0] at most of the places now. Co-developed-by: Krzysztof Kozlowski Signed-off-by: Krzysztof Kozlowski Signed-off-by: Viresh Kumar Tested-by: Dmitry Osipenko Tested-by: Jon Hunter --- drivers/opp/core.c | 165 ++++++++++++++++++++++++++++------------- drivers/opp/debugfs.c | 27 ++++++- drivers/opp/of.c | 67 +++++++++++++---- drivers/opp/opp.h | 16 ++-- include/linux/pm_opp.h | 7 +- 5 files changed, 208 insertions(+), 74 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 6368ae2d7360..1e143bd8e589 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -177,7 +177,7 @@ unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *op= p) return 0; } =20 - return opp->rate; + return opp->rates[0]; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); =20 @@ -426,7 +426,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); /* Helpers to read keys */ static unsigned long _read_freq(struct dev_pm_opp *opp, int index) { - return opp->rate; + return opp->rates[0]; } =20 static unsigned long _read_level(struct dev_pm_opp *opp, int index) @@ -766,8 +766,9 @@ static int _set_opp_voltage(struct device *dev, struct = regulator *reg, return ret; } =20 -static inline int _generic_set_opp_clk_only(struct device *dev, - struct opp_table *opp_table, struct dev_pm_opp *opp, void *data) +static int +_opp_config_clk_single(struct device *dev, struct opp_table *opp_table, + struct dev_pm_opp *opp, void *data, bool scaling_down) { unsigned long *target =3D data; unsigned long freq; @@ -781,7 +782,7 @@ static inline int _generic_set_opp_clk_only(struct devi= ce *dev, if (target) { freq =3D *target; } else if (opp) { - freq =3D opp->rate; + freq =3D opp->rates[0]; } else { WARN_ON(1); return -EINVAL; @@ -1007,11 +1008,11 @@ static int _set_opp(struct device *dev, struct opp_= table *opp_table, } =20 dev_dbg(dev, "%s: switching OPP: Freq %lu -> %lu Hz, Level %u -> %u, Bw %= u -> %u\n", - __func__, old_opp->rate, opp->rate, old_opp->level, opp->level, - old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0, + __func__, old_opp->rates[0], opp->rates[0], old_opp->level, + opp->level, old_opp->bandwidth ? old_opp->bandwidth[0].peak : 0, opp->bandwidth ? opp->bandwidth[0].peak : 0); =20 - scaling_down =3D _opp_compare_key(old_opp, opp); + scaling_down =3D _opp_compare_key(opp_table, old_opp, opp); if (scaling_down =3D=3D -1) scaling_down =3D 0; =20 @@ -1041,7 +1042,7 @@ static int _set_opp(struct device *dev, struct opp_ta= ble *opp_table, } } =20 - ret =3D _generic_set_opp_clk_only(dev, opp_table, opp, clk_data); + ret =3D opp_table->config_clks(dev, opp_table, opp, clk_data, scaling_dow= n); if (ret) return ret; =20 @@ -1115,8 +1116,8 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned = long target_freq) * equivalent to a clk_set_rate() */ if (!_get_opp_count(opp_table)) { - ret =3D _generic_set_opp_clk_only(dev, opp_table, NULL, - &target_freq); + ret =3D opp_table->config_clks(dev, opp_table, NULL, + &target_freq, false); goto put_opp_table; } =20 @@ -1237,6 +1238,8 @@ static struct opp_table *_allocate_opp_table(struct d= evice *dev, int index) INIT_LIST_HEAD(&opp_table->dev_list); INIT_LIST_HEAD(&opp_table->lazy); =20 + opp_table->clk =3D ERR_PTR(-ENODEV); + /* Mark regulator count uninitialized */ opp_table->regulator_count =3D -1; =20 @@ -1283,18 +1286,22 @@ static struct opp_table *_update_opp_table_clk(stru= ct device *dev, int ret; =20 /* - * Return early if we don't need to get clk or we have already tried it + * Return early if we don't need to get clk or we have already done it * earlier. */ - if (!getclk || IS_ERR(opp_table) || opp_table->clk) + if (!getclk || IS_ERR(opp_table) || !IS_ERR(opp_table->clk) || + opp_table->clks) return opp_table; =20 /* Find clk for the device */ opp_table->clk =3D clk_get(dev, NULL); =20 ret =3D PTR_ERR_OR_ZERO(opp_table->clk); - if (!ret) + if (!ret) { + opp_table->config_clks =3D _opp_config_clk_single; + opp_table->clk_count =3D 1; return opp_table; + } =20 if (ret =3D=3D -ENOENT) { dev_dbg(dev, "%s: Couldn't find clock: %d\n", __func__, ret); @@ -1399,7 +1406,7 @@ static void _opp_table_kref_release(struct kref *kref) =20 _of_clear_opp_table(opp_table); =20 - /* Release clk */ + /* Release automatically acquired single clk */ if (!IS_ERR(opp_table->clk)) clk_put(opp_table->clk); =20 @@ -1487,7 +1494,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned l= ong freq) mutex_lock(&opp_table->lock); =20 list_for_each_entry(iter, &opp_table->opp_list, node) { - if (iter->rate =3D=3D freq) { + if (iter->rates[0] =3D=3D freq) { opp =3D iter; break; } @@ -1594,24 +1601,28 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_remove_all_dynamic); struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table) { struct dev_pm_opp *opp; - int supply_count, supply_size, icc_size; + int supply_count, supply_size, icc_size, clk_size; =20 /* Allocate space for at least one supply */ supply_count =3D opp_table->regulator_count > 0 ? opp_table->regulator_count : 1; supply_size =3D sizeof(*opp->supplies) * supply_count; + clk_size =3D sizeof(*opp->rates) * opp_table->clk_count; icc_size =3D sizeof(*opp->bandwidth) * opp_table->path_count; =20 /* allocate new OPP node and supplies structures */ opp =3D kzalloc(sizeof(*opp) + supply_size + icc_size, GFP_KERNEL); - if (!opp) return NULL; =20 - /* Put the supplies at the end of the OPP structure as an empty array */ + /* Put the supplies, bw and clock at the end of the OPP structure */ opp->supplies =3D (struct dev_pm_opp_supply *)(opp + 1); + + opp->rates =3D (unsigned long *)(opp->supplies + supply_count); + if (icc_size) - opp->bandwidth =3D (struct dev_pm_opp_icc_bw *)(opp->supplies + supply_c= ount); + opp->bandwidth =3D (struct dev_pm_opp_icc_bw *)(opp->rates + opp_table->= clk_count); + INIT_LIST_HEAD(&opp->node); =20 return opp; @@ -1648,10 +1659,11 @@ static bool _opp_supported_by_regulators(struct dev= _pm_opp *opp, * 1: opp1 > opp2 * -1: opp1 < opp2 */ -int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2) +int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1, + struct dev_pm_opp *opp2) { - if (opp1->rate !=3D opp2->rate) - return opp1->rate < opp2->rate ? -1 : 1; + if (opp_table->clk_count =3D=3D 1 && opp1->rates[0] !=3D opp2->rates[0]) + return opp1->rates[0] < opp2->rates[0] ? -1 : 1; if (opp1->bandwidth && opp2->bandwidth && opp1->bandwidth[0].peak !=3D opp2->bandwidth[0].peak) return opp1->bandwidth[0].peak < opp2->bandwidth[0].peak ? -1 : 1; @@ -1676,7 +1688,7 @@ static int _opp_is_duplicate(struct device *dev, stru= ct dev_pm_opp *new_opp, * loop. */ list_for_each_entry(opp, &opp_table->opp_list, node) { - opp_cmp =3D _opp_compare_key(new_opp, opp); + opp_cmp =3D _opp_compare_key(opp_table, new_opp, opp); if (opp_cmp > 0) { *head =3D &opp->node; continue; @@ -1687,8 +1699,8 @@ static int _opp_is_duplicate(struct device *dev, stru= ct dev_pm_opp *new_opp, =20 /* Duplicate OPPs */ dev_warn(dev, "%s: duplicate OPPs detected. Existing: freq: %lu, volt: %= lu, enabled: %d. New: freq: %lu, volt: %lu, enabled: %d\n", - __func__, opp->rate, opp->supplies[0].u_volt, - opp->available, new_opp->rate, + __func__, opp->rates[0], opp->supplies[0].u_volt, + opp->available, new_opp->rates[0], new_opp->supplies[0].u_volt, new_opp->available); =20 /* Should we compare voltages for all regulators here ? */ @@ -1709,7 +1721,7 @@ void _required_opps_available(struct dev_pm_opp *opp,= int count) =20 opp->available =3D false; pr_warn("%s: OPP not supported by required OPP %pOF (%lu)\n", - __func__, opp->required_opps[i]->np, opp->rate); + __func__, opp->required_opps[i]->np, opp->rates[0]); return; } } @@ -1750,7 +1762,7 @@ int _opp_add(struct device *dev, struct dev_pm_opp *n= ew_opp, if (!_opp_supported_by_regulators(new_opp, opp_table)) { new_opp->available =3D false; dev_warn(dev, "%s: OPP not supported by regulators (%lu)\n", - __func__, new_opp->rate); + __func__, new_opp->rates[0]); } =20 /* required-opps not fully initialized yet */ @@ -1796,7 +1808,7 @@ int _opp_add_v1(struct opp_table *opp_table, struct d= evice *dev, return -ENOMEM; =20 /* populate the opp table */ - new_opp->rate =3D freq; + new_opp->rates[0] =3D freq; tol =3D u_volt * opp_table->voltage_tolerance_v1 / 100; new_opp->supplies[0].u_volt =3D u_volt; new_opp->supplies[0].u_volt_min =3D u_volt - tol; @@ -1991,6 +2003,17 @@ static void _opp_put_regulators(struct opp_table *op= p_table) opp_table->regulator_count =3D -1; } =20 +static void _put_clks(struct opp_table *opp_table, int count) +{ + int i; + + for (i =3D count - 1; i >=3D 0; i--) + clk_put(opp_table->clks[i]); + + kfree(opp_table->clks); + opp_table->clks =3D NULL; +} + /** * _opp_set_clknames() - Set clk names for the device * @dev: Device for which clk names is being set. @@ -2005,30 +2028,66 @@ static void _opp_put_regulators(struct opp_table *o= pp_table) * This must be called before any OPPs are initialized for the device. */ static int _opp_set_clknames(struct opp_table *opp_table, struct device *d= ev, - const char * const names[], unsigned int count) + const char * const names[], unsigned int count, + config_clks_t config_clks) { - /* We support only one clock name for now */ - if (count !=3D 1) + struct clk *clk; + int ret, i; + + /* Fail early for invalid configurations */ + if (!count || (config_clks && count =3D=3D 1) || (!config_clks && count >= 1)) return -EINVAL; =20 /* Another CPU that shares the OPP table has set the clkname ? */ - if (opp_table->clk_configured) + if (opp_table->clks) return 0; =20 - /* clk shouldn't be initialized at this point */ - if (WARN_ON(opp_table->clk)) - return -EBUSY; + opp_table->clks =3D kmalloc_array(count, sizeof(*opp_table->clks), + GFP_KERNEL); + if (!opp_table->clks) + return -ENOMEM; =20 - /* Find clk for the device */ - opp_table->clk =3D clk_get(dev, names[0]); - if (IS_ERR(opp_table->clk)) { - return dev_err_probe(dev, PTR_ERR(opp_table->clk), - "%s: Couldn't find clock\n", __func__); + /* Find clks for the device */ + for (i =3D 0; i < count; i++) { + clk =3D clk_get(dev, names[i]); + if (IS_ERR(clk)) { + ret =3D dev_err_probe(dev, PTR_ERR(clk), + "%s: Couldn't find clock with name: %s\n", + __func__, names[i]); + goto free_clks; + } + + opp_table->clks[i] =3D clk; } =20 - opp_table->clk_configured =3D true; + opp_table->clk_count =3D count; + + /* Set generic single clk set here */ + if (count =3D=3D 1) { + opp_table->config_clks =3D _opp_config_clk_single; + + /* + * We could have just dropped the "clk" field and used "clks" + * everywhere. Instead we kept the "clk" field around for + * following reasons: + * + * - avoiding clks[0] everywhere else. + * - not running single clk helpers for multiple clk usecase by + * mistake. + * + * Since this is single-clk case, just update the clk pointer + * too. + */ + opp_table->clk =3D opp_table->clks[0]; + } else { + opp_table->config_clks =3D config_clks; + } =20 return 0; + +free_clks: + _put_clks(opp_table, i); + return ret; } =20 /** @@ -2037,11 +2096,13 @@ static int _opp_set_clknames(struct opp_table *opp_= table, struct device *dev, */ static void _opp_put_clknames(struct opp_table *opp_table) { - if (opp_table->clk_configured) { - clk_put(opp_table->clk); - opp_table->clk =3D ERR_PTR(-EINVAL); - opp_table->clk_configured =3D false; - } + if (!opp_table->clks) + return; + + opp_table->config_clks =3D NULL; + opp_table->clk =3D ERR_PTR(-ENODEV); + + _put_clks(opp_table, opp_table->clk_count); } =20 /** @@ -2225,9 +2286,13 @@ struct opp_table *dev_pm_opp_set_config(struct devic= e *dev, /* Configure clocks */ if (config->clk_names) { ret =3D _opp_set_clknames(opp_table, dev, config->clk_names, - config->clk_count); + config->clk_count, config->config_clks); if (ret) goto err; + } else if (config->config_clks) { + /* Don't allow config callback without clocks */ + ret =3D -EINVAL; + goto err; } =20 /* Configure property names */ @@ -2523,7 +2588,7 @@ static int _opp_set_availability(struct device *dev, = unsigned long freq, =20 /* Do we have the frequency? */ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) { - if (tmp_opp->rate =3D=3D freq) { + if (tmp_opp->rates[0] =3D=3D freq) { opp =3D tmp_opp; break; } @@ -2594,7 +2659,7 @@ int dev_pm_opp_adjust_voltage(struct device *dev, uns= igned long freq, =20 /* Do we have the frequency? */ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) { - if (tmp_opp->rate =3D=3D freq) { + if (tmp_opp->rates[0] =3D=3D freq) { opp =3D tmp_opp; break; } diff --git a/drivers/opp/debugfs.c b/drivers/opp/debugfs.c index 1b6e5c55c3ed..402c507edac7 100644 --- a/drivers/opp/debugfs.c +++ b/drivers/opp/debugfs.c @@ -74,6 +74,24 @@ static void opp_debug_create_bw(struct dev_pm_opp *opp, } } =20 +static void opp_debug_create_clks(struct dev_pm_opp *opp, + struct opp_table *opp_table, + struct dentry *pdentry) +{ + char name[12]; + int i; + + if (opp_table->clk_count =3D=3D 1) { + debugfs_create_ulong("rate_hz", S_IRUGO, pdentry, &opp->rates[0]); + return; + } + + for (i =3D 0; i < opp_table->clk_count; i++) { + snprintf(name, sizeof(name), "rate_hz_%d", i); + debugfs_create_ulong(name, S_IRUGO, pdentry, &opp->rates[i]); + } +} + static void opp_debug_create_supplies(struct dev_pm_opp *opp, struct opp_table *opp_table, struct dentry *pdentry) @@ -117,10 +135,11 @@ void opp_debug_create_one(struct dev_pm_opp *opp, str= uct opp_table *opp_table) * Get directory name for OPP. * * - Normally rate is unique to each OPP, use it to get unique opp-name. - * - For some devices rate isn't available, use index instead. + * - For some devices rate isn't available or there are multiple, use + * index instead for them. */ - if (likely(opp->rate)) - id =3D opp->rate; + if (likely(opp_table->clk_count =3D=3D 1)) + id =3D opp->rates[0]; else id =3D _get_opp_count(opp_table); =20 @@ -134,7 +153,6 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struc= t opp_table *opp_table) debugfs_create_bool("turbo", S_IRUGO, d, &opp->turbo); debugfs_create_bool("suspend", S_IRUGO, d, &opp->suspend); debugfs_create_u32("performance_state", S_IRUGO, d, &opp->pstate); - debugfs_create_ulong("rate_hz", S_IRUGO, d, &opp->rate); debugfs_create_u32("level", S_IRUGO, d, &opp->level); debugfs_create_ulong("clock_latency_ns", S_IRUGO, d, &opp->clock_latency_ns); @@ -142,6 +160,7 @@ void opp_debug_create_one(struct dev_pm_opp *opp, struc= t opp_table *opp_table) opp->of_name =3D of_node_full_name(opp->np); debugfs_create_str("of_name", S_IRUGO, d, (char **)&opp->of_name); =20 + opp_debug_create_clks(opp, opp_table, d); opp_debug_create_supplies(opp, opp_table, d); opp_debug_create_bw(opp, opp_table, d); =20 diff --git a/drivers/opp/of.c b/drivers/opp/of.c index 843923ab9d66..ea8fc9e1f7e3 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -767,6 +767,53 @@ void dev_pm_opp_of_remove_table(struct device *dev) } EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); =20 +static int _read_rate(struct dev_pm_opp *new_opp, struct opp_table *opp_ta= ble, + struct device_node *np) +{ + struct property *prop; + int i, count, ret; + u64 *rates; + + if (!opp_table->clk_count) + return 0; + + prop =3D of_find_property(np, "opp-hz", NULL); + if (!prop) + return -ENODEV; + + count =3D prop->length / sizeof(u64); + if (opp_table->clk_count !=3D count) { + pr_err("%s: Count mismatch between opp-hz and clk_count (%d %d)\n", + __func__, count, opp_table->clk_count); + return -EINVAL; + } + + rates =3D kmalloc_array(count, sizeof(*rates), GFP_KERNEL); + if (!rates) + return -ENOMEM; + + ret =3D of_property_read_u64_array(np, "opp-hz", rates, count); + if (ret) { + pr_err("%s: Error parsing opp-hz: %d\n", __func__, ret); + } else { + /* + * Rate is defined as an unsigned long in clk API, and so + * casting explicitly to its type. Must be fixed once rate is 64 + * bit guaranteed in clk API. + */ + for (i =3D 0; i < count; i++) { + new_opp->rates[i] =3D (unsigned long)rates[i]; + + /* This will happen for frequencies > 4.29 GHz */ + WARN_ON(new_opp->rates[i] !=3D rates[i]); + } + } + + kfree(rates); + + return ret; +} + static int _read_bw(struct dev_pm_opp *new_opp, struct opp_table *opp_tabl= e, struct device_node *np, bool peak) { @@ -812,19 +859,13 @@ static int _read_opp_key(struct dev_pm_opp *new_opp, struct opp_table *opp_table, struct device_node *np) { bool found =3D false; - u64 rate; int ret; =20 - ret =3D of_property_read_u64(np, "opp-hz", &rate); - if (!ret) { - /* - * Rate is defined as an unsigned long in clk API, and so - * casting explicitly to its type. Must be fixed once rate is 64 - * bit guaranteed in clk API. - */ - new_opp->rate =3D (unsigned long)rate; + ret =3D _read_rate(new_opp, opp_table, np); + if (ret) + return ret; + else if (opp_table->clk_count =3D=3D 1) found =3D true; - } =20 /* * Bandwidth consists of peak and average (optional) values: @@ -893,8 +934,8 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp= _table *opp_table, =20 /* Check if the OPP supports hardware's hierarchy of versions or not */ if (!_opp_is_supported(dev, opp_table, np)) { - dev_dbg(dev, "OPP not supported by hardware: %lu\n", - new_opp->rate); + dev_dbg(dev, "OPP not supported by hardware: %s\n", + of_node_full_name(np)); goto free_opp; } =20 @@ -945,7 +986,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp= _table *opp_table, opp_table->clock_latency_ns_max =3D new_opp->clock_latency_ns; =20 pr_debug("%s: turbo:%d rate:%lu uv:%lu uvmin:%lu uvmax:%lu latency:%lu le= vel:%u\n", - __func__, new_opp->turbo, new_opp->rate, + __func__, new_opp->turbo, new_opp->rates[0], new_opp->supplies[0].u_volt, new_opp->supplies[0].u_volt_min, new_opp->supplies[0].u_volt_max, new_opp->clock_latency_ns, new_opp->level); diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h index 131fc7c05db8..d5e8e2bd5e9a 100644 --- a/drivers/opp/opp.h +++ b/drivers/opp/opp.h @@ -58,7 +58,7 @@ extern struct list_head opp_tables, lazy_opp_tables; * @suspend: true if suspend OPP * @removed: flag indicating that OPP's reference is dropped by OPP core. * @pstate: Device's power domain's performance state. - * @rate: Frequency in hertz + * @rates: Frequencies in hertz * @level: Performance level * @supplies: Power supplies voltage/current values * @bandwidth: Interconnect bandwidth values @@ -81,7 +81,7 @@ struct dev_pm_opp { bool suspend; bool removed; unsigned int pstate; - unsigned long rate; + unsigned long *rates; unsigned int level; =20 struct dev_pm_opp_supply *supplies; @@ -149,8 +149,10 @@ enum opp_table_access { * @supported_hw: Array of version number to support. * @supported_hw_count: Number of elements in supported_hw array. * @prop_name: A name to postfix to many DT properties, while parsing them. - * @clk_configured: Clock name is configured by the platform. - * @clk: Device's clock handle + * @config_clks: Platform specific config_clks() callback. + * @clks: Device's clock handles, for multiple clocks. + * @clk: Device's clock handle, for single clock. + * @clk_count: Number of clocks. * @config_regulators: Platform specific config_regulators() callback. * @regulators: Supply regulators * @regulator_count: Number of power supply regulators. Its value can be -1 @@ -199,8 +201,10 @@ struct opp_table { unsigned int *supported_hw; unsigned int supported_hw_count; const char *prop_name; - bool clk_configured; + config_clks_t config_clks; + struct clk **clks; struct clk *clk; + int clk_count; config_regulators_t config_regulators; struct regulator **regulators; int regulator_count; @@ -225,7 +229,7 @@ struct opp_table *_find_opp_table(struct device *dev); struct opp_device *_add_opp_dev(const struct device *dev, struct opp_table= *opp_table); struct dev_pm_opp *_opp_allocate(struct opp_table *opp_table); void _opp_free(struct dev_pm_opp *opp); -int _opp_compare_key(struct dev_pm_opp *opp1, struct dev_pm_opp *opp2); +int _opp_compare_key(struct opp_table *opp_table, struct dev_pm_opp *opp1,= struct dev_pm_opp *opp2); int _opp_add(struct device *dev, struct dev_pm_opp *new_opp, struct opp_ta= ble *opp_table); int _opp_add_v1(struct opp_table *opp_table, struct device *dev, unsigned = long freq, long u_volt, bool dynamic); void _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, int l= ast_cpu); diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 3a81885e976a..74fbb7515128 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -61,10 +61,14 @@ typedef int (*config_regulators_t)(struct device *dev, struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, struct regulator **regulators, unsigned int count); =20 +typedef int (*config_clks_t)(struct device *dev, struct opp_table *opp_tab= le, + struct dev_pm_opp *opp, void *data, bool scaling_down); + /** * struct dev_pm_opp_config - Device OPP configuration values * @clk_names: Clk name. - * @clk_count: Number of clocks, max 1 for now. + * @clk_count: Number of clocks. + * @config_clks: Custom set clk helper. * @prop_name: Name to postfix to properties. * @config_regulators: Custom set regulator helper. * @supported_hw: Array of hierarchy of versions to match. @@ -80,6 +84,7 @@ typedef int (*config_regulators_t)(struct device *dev, struct dev_pm_opp_config { const char * const *clk_names; unsigned int clk_count; + config_clks_t config_clks; const char *prop_name; config_regulators_t config_regulators; unsigned int *supported_hw; --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 786CDC43334 for ; Fri, 10 Jun 2022 08:24:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347049AbiFJIY6 (ORCPT ); Fri, 10 Jun 2022 04:24:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347657AbiFJIYV (ORCPT ); Fri, 10 Jun 2022 04:24:21 -0400 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81A6B3F6EF8 for ; Fri, 10 Jun 2022 01:21:22 -0700 (PDT) Received: by mail-pg1-x531.google.com with SMTP id s135so8488493pgs.10 for ; Fri, 10 Jun 2022 01:21:22 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=LHHuKFlrfiwau/eix3fAQG/B41w5f5VbH6st3U+c9yg=; b=qpRmeBDFnpX+0rY9SPHC4csJPf3+qr18qzno5cixRFke77gbJUAkX/VMqrLgU6AXz8 AVoPCidOJ5FJ6OCUtZOFEUJzbajcL58+Uo4SAMH5O1KZwIhMT+hkHvsUPlLEmZ/Hdy7z ttAeeW6fBuTZ61Ip3SLGhRrDJmu//KCr/lbwYeX5QbVlFnH/R+etNSOLv5Luz/YHeV9b PvtMra1SxtNGVebOXEatzvyGuSxHyoWYs+vzozH7lDgEZuoP219BrvEYCHD7LqcQeaWS I67XKVdw4zP3xKQpBcCUYvdTx0cjLEOmiSAka21bQLLYTrXymehCuzA4gmtqiPz8p8Pt zn/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=LHHuKFlrfiwau/eix3fAQG/B41w5f5VbH6st3U+c9yg=; b=ujVnSr0knM//hfzOW5HHlO5Flb+9l2fWLjuFqP3/mzFCA3e6BCRmL0d10fHeOI7Ywt r2FclVoqi7II/EmDE3bRDJg7zOA+CmJSVa9EsjqKpNZluEqgBD1GYNB63hOIv9fRCIC8 TwURFFKhmxAeRCe6r7rK0kmpJfkabBv+06jpGNL6gNsJkBsSfqv+7qzA3kXeiLNybW4c BCeKdXB14JbPAz8F/M3V5dti/JqQaiLhZl6ErRZnVAz4OKImbjW/KOMMPmTDXDaMd/LM Anhq8NgHXi2nk86vJ4TmbpLLzucnXg10qvGY+LCf7VKIClBKm5hmWOC4AKH1cNjKDT0h ZYOA== X-Gm-Message-State: AOAM533uTJmnLPgOOs4ixk0y8m17cmS7FiLISW89BTvDtYmdaTLe6l0U rXZn3clTQFZwUzXrmVxYa3zS5MRZcoJPgw== X-Google-Smtp-Source: ABdhPJw8Dg0/0KuozXdpvKCtDw5sE3Runm5YTRBLrbg/SZwW+IZDbktvS84eJDcilFAzRr6i6aPRuw== X-Received: by 2002:a63:fd48:0:b0:3fd:a873:aae4 with SMTP id m8-20020a63fd48000000b003fda873aae4mr23306412pgj.492.1654849281898; Fri, 10 Jun 2022 01:21:21 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id o62-20020a17090a0a4400b001e2b19e6cfesm1092544pjo.12.2022.06.10.01.21.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:21 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 6/8] OPP: Add key specific assert() method to key finding helpers Date: Fri, 10 Jun 2022 13:50:50 +0530 Message-Id: <6afbc4c795216b31c200ae0c19072403a1caab2f.1654849214.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The helpers for the clock key, at least, would need to assert that the helpers are called only for single clock case. Prepare for that by adding an argument to the key finding helpers. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 56 +++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 1e143bd8e589..b8e6dc0a9b36 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -477,10 +477,15 @@ static struct dev_pm_opp *_opp_table_find_key(struct = opp_table *opp_table, unsigned long *key, int index, bool available, unsigned long (*read)(struct dev_pm_opp *opp, int index), bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, - unsigned long opp_key, unsigned long key)) + unsigned long opp_key, unsigned long key), + bool (*assert)(struct opp_table *opp_table)) { struct dev_pm_opp *temp_opp, *opp =3D ERR_PTR(-ERANGE); =20 + /* Assert that the requirement is met */ + if (assert && !assert(opp_table)) + return ERR_PTR(-EINVAL); + mutex_lock(&opp_table->lock); =20 list_for_each_entry(temp_opp, &opp_table->opp_list, node) { @@ -505,7 +510,8 @@ static struct dev_pm_opp * _find_key(struct device *dev, unsigned long *key, int index, bool availabl= e, unsigned long (*read)(struct dev_pm_opp *opp, int index), bool (*compare)(struct dev_pm_opp **opp, struct dev_pm_opp *temp_opp, - unsigned long opp_key, unsigned long key)) + unsigned long opp_key, unsigned long key), + bool (*assert)(struct opp_table *opp_table)) { struct opp_table *opp_table; struct dev_pm_opp *opp; @@ -518,7 +524,7 @@ _find_key(struct device *dev, unsigned long *key, int i= ndex, bool available, } =20 opp =3D _opp_table_find_key(opp_table, key, index, available, read, - compare); + compare, assert); =20 dev_pm_opp_put_opp_table(opp_table); =20 @@ -527,35 +533,42 @@ _find_key(struct device *dev, unsigned long *key, int= index, bool available, =20 static struct dev_pm_opp *_find_key_exact(struct device *dev, unsigned long key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { /* * The value of key will be updated here, but will be ignored as the * caller doesn't need it. */ - return _find_key(dev, &key, index, available, read, _compare_exact); + return _find_key(dev, &key, index, available, read, _compare_exact, + assert); } =20 static struct dev_pm_opp *_opp_table_find_key_ceil(struct opp_table *opp_t= able, unsigned long *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { return _opp_table_find_key(opp_table, key, index, available, read, - _compare_ceil); + _compare_ceil, assert); } =20 static struct dev_pm_opp *_find_key_ceil(struct device *dev, unsigned long= *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { - return _find_key(dev, key, index, available, read, _compare_ceil); + return _find_key(dev, key, index, available, read, _compare_ceil, + assert); } =20 static struct dev_pm_opp *_find_key_floor(struct device *dev, unsigned long *key, int index, bool available, - unsigned long (*read)(struct dev_pm_opp *opp, int index)) + unsigned long (*read)(struct dev_pm_opp *opp, int index), + bool (*assert)(struct opp_table *opp_table)) { - return _find_key(dev, key, index, available, read, _compare_floor); + return _find_key(dev, key, index, available, read, _compare_floor, + assert); } =20 /** @@ -584,14 +597,15 @@ static struct dev_pm_opp *_find_key_floor(struct devi= ce *dev, struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { - return _find_key_exact(dev, freq, 0, available, _read_freq); + return _find_key_exact(dev, freq, 0, available, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); =20 static noinline struct dev_pm_opp *_find_freq_ceil(struct opp_table *opp_t= able, unsigned long *freq) { - return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq); + return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq, + NULL); } =20 /** @@ -615,7 +629,7 @@ static noinline struct dev_pm_opp *_find_freq_ceil(stru= ct opp_table *opp_table, struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { - return _find_key_ceil(dev, freq, 0, true, _read_freq); + return _find_key_ceil(dev, freq, 0, true, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); =20 @@ -640,7 +654,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { - return _find_key_floor(dev, freq, 0, true, _read_freq); + return _find_key_floor(dev, freq, 0, true, _read_freq, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); =20 @@ -662,7 +676,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); struct dev_pm_opp *dev_pm_opp_find_level_exact(struct device *dev, unsigned int level) { - return _find_key_exact(dev, level, 0, true, _read_level); + return _find_key_exact(dev, level, 0, true, _read_level, NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_exact); =20 @@ -684,8 +698,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_exact); struct dev_pm_opp *dev_pm_opp_find_level_ceil(struct device *dev, unsigned int *level) { - return _find_key_ceil(dev, (unsigned long *)level, 0, true, - _read_level); + return _find_key_ceil(dev, (unsigned long *)level, 0, true, _read_level, + NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_ceil); =20 @@ -711,7 +725,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_level_ceil); struct dev_pm_opp *dev_pm_opp_find_bw_ceil(struct device *dev, unsigned in= t *bw, int index) { - return _find_key_ceil(dev, (unsigned long *)bw, index, true, _read_bw); + return _find_key_ceil(dev, (unsigned long *)bw, index, true, _read_bw, + NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_bw_ceil); =20 @@ -737,7 +752,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_bw_ceil); struct dev_pm_opp *dev_pm_opp_find_bw_floor(struct device *dev, unsigned int *bw, int index) { - return _find_key_floor(dev, (unsigned long *)bw, index, true, _read_bw); + return _find_key_floor(dev, (unsigned long *)bw, index, true, _read_bw, + NULL); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_bw_floor); =20 --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 319E7C43334 for ; Fri, 10 Jun 2022 08:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244976AbiFJIZK (ORCPT ); Fri, 10 Jun 2022 04:25:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60418 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346743AbiFJIYh (ORCPT ); Fri, 10 Jun 2022 04:24:37 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A75B53FB122 for ; Fri, 10 Jun 2022 01:21:25 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id e9so12900290pju.5 for ; Fri, 10 Jun 2022 01:21:25 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=e9IQH3f+hWlu/9/XT0cEj9lqHfnbsk8bolxLv7nv6D0=; b=nC/e0rCWWccgg+dWFsl2cdg+XLCq5mE001XmdFOx5bsYyPfjbc5YkOzCUgUHvuk10M 76cSux1zFPmYh5zOtYB2Igosm+xdMGD2ZU1pgGnUXeLEWQPx+AJS6EnEkyUNuuL1n1Ft 8QTxgSlNakQZhWlA90Bl+vUNZySfTeRYw/aga3tV8/1x+omQGwf9B7T+fb4N/6TAKN1x hBs6zRb1MxNx7+fPp1522M/k/p03ulpvJiobwYGNmzcrTKr55UpISIdFUP4LKxjtpYRU uujF6bf0TqOfaGyB2pOS2YGlOh8m1Pda2hc8mjAQYEoq5ETMa2tI77FQhvrFc/E0JPt0 2dNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e9IQH3f+hWlu/9/XT0cEj9lqHfnbsk8bolxLv7nv6D0=; b=lBVxSvQ02uNe7DCsAdotXomJ0XNp7PKMm1Hd+17uyA9/J81646cf5YWH6aMfIyuYnY TIXnAPOZ2q1e/5fa910dP28n83T9nO72M+k2jl9x1+pytGULumu6mCmV5k41rJA80+wr ZqfcVSn7dft2k/cBvDFp53IhfyGMQqslIpRMBfQajS4qy4jD1zKnghvQao06YZ1ICMXM lUrQHmoUfbYjwXKIM8dIqHkNTFBaP+MSpQb7ASI1Pz9nuPhFLb+6T4UPkMNq2PVFS3xg JTPN++wcEZ1rTjGU0t7tzx9urbcyTT9dbeo6dqYQUyzgjCimVWhnsNIj8VATfOpUuhax Zpeg== X-Gm-Message-State: AOAM530A5rOt7Em9HPS+VI7XyIi1OSGqQpTu5vUCWpMmtAGtc/9mjr+J x6xEyukr5fRRkV+LMKx9jx1rGA== X-Google-Smtp-Source: ABdhPJzi/0ZgaUsiiXZ34sJtcUMki2ea9mVcEE3SSAZi1r84WghHlJPIkMNeBasiZBmCiDVXJVK2rA== X-Received: by 2002:a17:902:ec81:b0:163:3142:e0dd with SMTP id x1-20020a170902ec8100b001633142e0ddmr37480633plg.40.1654849284635; Fri, 10 Jun 2022 01:21:24 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id iz12-20020a170902ef8c00b00162037fbb68sm18132723plb.215.2022.06.10.01.21.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:24 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 7/8] OPP: Assert clk_count == 1 for single clk helpers Date: Fri, 10 Jun 2022 13:50:51 +0530 Message-Id: X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Many helpers can be safely called only for devices that have a single clk associated with them. Assert the same for those routines. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index b8e6dc0a9b36..5635f4ad6d59 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -93,6 +93,12 @@ struct opp_table *_find_opp_table(struct device *dev) return opp_table; } =20 +/* Returns true for single clock, false with WARN otherwise */ +bool assert_single_clk(struct opp_table *opp_table) +{ + return !WARN_ON(opp_table->clk_count !=3D 1); +} + /** * dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp * @opp: opp for which voltage has to be returned for @@ -177,6 +183,9 @@ unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *op= p) return 0; } =20 + if (!assert_single_clk(opp->opp_table)) + return 0; + return opp->rates[0]; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_freq); @@ -597,7 +606,8 @@ static struct dev_pm_opp *_find_key_floor(struct device= *dev, struct dev_pm_opp *dev_pm_opp_find_freq_exact(struct device *dev, unsigned long freq, bool available) { - return _find_key_exact(dev, freq, 0, available, _read_freq, NULL); + return _find_key_exact(dev, freq, 0, available, _read_freq, + assert_single_clk); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_exact); =20 @@ -605,7 +615,7 @@ static noinline struct dev_pm_opp *_find_freq_ceil(stru= ct opp_table *opp_table, unsigned long *freq) { return _opp_table_find_key_ceil(opp_table, freq, 0, true, _read_freq, - NULL); + assert_single_clk); } =20 /** @@ -629,7 +639,7 @@ static noinline struct dev_pm_opp *_find_freq_ceil(stru= ct opp_table *opp_table, struct dev_pm_opp *dev_pm_opp_find_freq_ceil(struct device *dev, unsigned long *freq) { - return _find_key_ceil(dev, freq, 0, true, _read_freq, NULL); + return _find_key_ceil(dev, freq, 0, true, _read_freq, assert_single_clk); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); =20 @@ -654,7 +664,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_ceil); struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev, unsigned long *freq) { - return _find_key_floor(dev, freq, 0, true, _read_freq, NULL); + return _find_key_floor(dev, freq, 0, true, _read_freq, assert_single_clk); } EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); =20 @@ -1507,6 +1517,9 @@ void dev_pm_opp_remove(struct device *dev, unsigned l= ong freq) if (IS_ERR(opp_table)) return; =20 + if (!assert_single_clk(opp_table)) + goto put_table; + mutex_lock(&opp_table->lock); =20 list_for_each_entry(iter, &opp_table->opp_list, node) { @@ -1528,6 +1541,7 @@ void dev_pm_opp_remove(struct device *dev, unsigned l= ong freq) __func__, freq); } =20 +put_table: /* Drop the reference taken by _find_opp_table() */ dev_pm_opp_put_opp_table(opp_table); } @@ -1819,6 +1833,9 @@ int _opp_add_v1(struct opp_table *opp_table, struct d= evice *dev, unsigned long tol; int ret; =20 + if (!assert_single_clk(opp_table)) + return -EINVAL; + new_opp =3D _opp_allocate(opp_table); if (!new_opp) return -ENOMEM; @@ -2600,6 +2617,11 @@ static int _opp_set_availability(struct device *dev,= unsigned long freq, return r; } =20 + if (!assert_single_clk(opp_table)) { + r =3D -EINVAL; + goto put_table; + } + mutex_lock(&opp_table->lock); =20 /* Do we have the frequency? */ @@ -2671,6 +2693,11 @@ int dev_pm_opp_adjust_voltage(struct device *dev, un= signed long freq, return r; } =20 + if (!assert_single_clk(opp_table)) { + r =3D -EINVAL; + goto put_table; + } + mutex_lock(&opp_table->lock); =20 /* Do we have the frequency? */ @@ -2702,11 +2729,11 @@ int dev_pm_opp_adjust_voltage(struct device *dev, u= nsigned long freq, opp); =20 dev_pm_opp_put(opp); - goto adjust_put_table; + goto put_table; =20 adjust_unlock: mutex_unlock(&opp_table->lock); -adjust_put_table: +put_table: dev_pm_opp_put_opp_table(opp_table); return r; } --=20 2.31.1.272.g89b43f80a514 From nobody Wed Apr 29 09:51:40 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F29D2C433EF for ; Fri, 10 Jun 2022 08:25:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347626AbiFJIZ0 (ORCPT ); Fri, 10 Jun 2022 04:25:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347631AbiFJIYn (ORCPT ); Fri, 10 Jun 2022 04:24:43 -0400 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50837263DE1 for ; Fri, 10 Jun 2022 01:21:28 -0700 (PDT) Received: by mail-pg1-x52a.google.com with SMTP id d129so24104556pgc.9 for ; Fri, 10 Jun 2022 01:21:28 -0700 (PDT) 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 :mime-version:content-transfer-encoding; bh=OUzjpkdJ+Oncv2pX+1niDcaxvElVVVJiI1pxvyK4stI=; b=OVEHPpNyDybpByzG4Og2VhdQn9E3yN7w1x1PHJ5Ue3QyiL3Zht3ZifjplCx2lqka+9 RKe2QfEAwUYpqo+Dvmf68WTvmtcyGFkZYTngl2BGmBFDHd+vY7LkSTWGAKryQ9XCvZ2O JHng0+Q1ZqGnStUDaocqHm2KV6DoL1Zkz4XLjVoT5NfBclEY/af0QkuZ/auvuMBFDrL6 HrxUUJ+xKe1pvo+B4FsPvqYTc1cogDL3Txll0g+pOMSFDDDkYSyfEgT/qalaAWFUVcUK +YUyjx+MkDb6RkZmN1AVkLF9tdddWBxkMnVcJV8ZC1KeklgMSnWraKHtW9B7jHShOkfp Qngg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OUzjpkdJ+Oncv2pX+1niDcaxvElVVVJiI1pxvyK4stI=; b=cgnElfYpY/X5kvodRIS1aPqauryxqXY/+6vUVTNkS3l8BpFW6sDku3F4fo3102TqO5 sp7JJXJsAFg3XXhQaPbi72oftUaUk2n4ZU9wtYB+9tCUmXR6vgx33vpOPUGU33eYbeM0 ny3uJr6yM0Kzs0IpyC1BAOaNR5E1a+rOPFt3Q70aZyD9sBoe9Lkg+Vh7iwzyIx9oYU2W TgCC04GIw4dLRXQj+yl65ANexL3fvH6YiliBQbx9VWDEuW5a+w4rcDEGpU1gdcFHRR1b /jKOnwdboXwWCJfDZp0Gztr1KcKFkmGk4OWTff2pZPF8H/QJQqjGJGgqpanfxtpxOyWj b7Nw== X-Gm-Message-State: AOAM531rBAHrLqFIBjjIhZYBb9EtUogi05Ptr8eBREg3r3rwYBNoU7do QeaFv3joiuH54N/AU161FWPET/cOp4dNYw== X-Google-Smtp-Source: ABdhPJy9fS1pS+m8xIVzcpT20JbS53iP38zAf+tndvGYCAK/poMTbNC3yPmuG94w0SE9XKervmyW8A== X-Received: by 2002:a05:6a00:1992:b0:51c:391f:6ff5 with SMTP id d18-20020a056a00199200b0051c391f6ff5mr19345170pfl.16.1654849287665; Fri, 10 Jun 2022 01:21:27 -0700 (PDT) Received: from localhost ([122.162.234.2]) by smtp.gmail.com with ESMTPSA id b8-20020a1709027e0800b0016777b33d41sm10318730plm.294.2022.06.10.01.21.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jun 2022 01:21:27 -0700 (PDT) From: Viresh Kumar To: Krzysztof Kozlowski , Viresh Kumar , Nishanth Menon , Stephen Boyd , "Rafael J. Wysocki" Cc: Viresh Kumar , linux-pm@vger.kernel.org, Vincent Guittot , linux-kernel@vger.kernel.org Subject: [PATCH 8/8] OPP: Provide a simple implementation to configure multiple clocks Date: Fri, 10 Jun 2022 13:50:52 +0530 Message-Id: <76c4db9b37866c60306d39ed982cba56af15ff00.1654849214.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This provides a simple implementation to configure multiple clocks for a device. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 10 ++++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 5635f4ad6d59..bb7be115a0c9 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -825,6 +825,40 @@ _opp_config_clk_single(struct device *dev, struct opp_= table *opp_table, return ret; } =20 +/* + * Simple implementation for configuring multiple clocks. Configure clocks= in + * the order in which they are present in the array while scaling up. + */ +int dev_pm_opp_config_clks_simple(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, + bool scaling_down) +{ + int ret, i; + + if (scaling_down) { + for (i =3D opp_table->clk_count - 1; i >=3D 0; i--) { + ret =3D clk_set_rate(opp_table->clks[i], opp->rates[i]); + if (ret) { + dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, + ret); + return ret; + } + } + } else { + for (i =3D 0; i < opp_table->clk_count; i++) { + ret =3D clk_set_rate(opp_table->clks[i], opp->rates[i]); + if (ret) { + dev_err(dev, "%s: failed to set clock rate: %d\n", __func__, + ret); + return ret; + } + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_opp_config_clks_simple); + static int _opp_config_regulator_single(struct device *dev, struct dev_pm_opp *old_opp, struct dev_pm_opp *new_opp, struct regulator **regulators, unsigned int count) diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 74fbb7515128..8e69b4e971d0 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -162,6 +162,9 @@ int dev_pm_opp_unregister_notifier(struct device *dev, = struct notifier_block *nb struct opp_table *dev_pm_opp_set_config(struct device *dev, struct dev_pm_= opp_config *config); int devm_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *c= onfig); void dev_pm_opp_clear_config(struct opp_table *opp_table); +int dev_pm_opp_config_clks_simple(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, + bool scaling_down); =20 struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_tab= le, 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); @@ -345,6 +348,13 @@ static inline int devm_pm_opp_set_config(struct device= *dev, struct dev_pm_opp_c =20 static inline void dev_pm_opp_clear_config(struct opp_table *opp_table) {} =20 +static inline int dev_pm_opp_config_clks_simple(struct device *dev, + struct opp_table *opp_table, struct dev_pm_opp *opp, void *data, + bool scaling_down) +{ + return -EOPNOTSUPP; +} + 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) { --=20 2.31.1.272.g89b43f80a514