From patchwork Thu Jan 21 11:17:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh Kumar X-Patchwork-Id: 12035647 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05F7EC433E6 for ; Thu, 21 Jan 2021 11:21:49 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B4B85238E1 for ; Thu, 21 Jan 2021 11:21:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B4B85238E1 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=dQVjgZzS76IVc1S9eWohWyrwV1XzcWH2ZtlRwo9ppTA=; b=WFYnpe1/gBks+8CFE0KEkZ0v3 M5Ndaum3DHddpPTvcjPiHKbQIfMI+JxZVKv8sw/C7UcObZ7UxwY1bwQUFLiQdQV37uQ/B9nCricoZ q88Jas71uShGr819Smjg3LXpL3g8952Ir51NIFuiRJ2IIkRj2HRiKmP0Dp3uJNX2jYkh7NXXiKGac /G2ZgnbpVwki31pv7XTIpmIFk0xCs/pi2kAyEGlguDZo8L/crvG5BHjgdYhx9VrezkAAmYQdsQWp6 cplSiE0yvIgNRkwhA9eVUSNzfpLXwbEXxuawVhmAOmX53hx0LKIxAOsf7CZpHPIBwH+9Wlba9qAPc kuw14J3ug==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2XzY-00052w-5d; Thu, 21 Jan 2021 11:19:08 +0000 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1l2XzN-0004yk-4O for linux-arm-kernel@lists.infradead.org; Thu, 21 Jan 2021 11:18:58 +0000 Received: by mail-pj1-x1034.google.com with SMTP id p15so1443768pjv.3 for ; Thu, 21 Jan 2021 03:18:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yGSozZ62BYCUnvHz15lG2EnbQmWJ88vlwijLJGHrCgo=; b=jMznsEDClSg4+xGGHd4ynKf8aBhP9BTp/c1fcRIW0bwCmouHvmrSfMLRDtlokUPLPV 7uZ6cisbhC2/bCQhc1Sf8gCz0qzy7gUIZQPY641HZOSD9Ne58dPVd1v3P52FQQFJDQ5r BIEh2MsMfTZXAeF2tHcy4OjrZF5MSsSSxlisois1xZMV8twzKfyA/YgxLL7chity4eV6 HqMTn0S0YphcvWIdJERsciBUfz3VyFW4wXWKZaGZwJW8ZeXt2D84zqcdL5KTQc00Owqp EKOGoSCDNRgLk8dZXgxqPtahXM2N2MsO9eo7nghpRuI4W7dDgRIhCNczCqPqveO8WmTe iNTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yGSozZ62BYCUnvHz15lG2EnbQmWJ88vlwijLJGHrCgo=; b=WdXMgUO2FuhNUPzpGVi6UlTdhit9bd1BD+R7Jq0JicmxpgH24tEXmQlP1u0cpdLeqy OkXlwRpC4iOM+3fXp2NJGzOi94G5fOAIOwzCuqGMoRlYqXxX4MqB2tTmqQ3PgfnUSmxT WRRXadwi4hak+MhPKwOMgw3Xodjn3qETKxS2j48j/g+NwfP47xINk+VbGe2QurGNmy+h uySZ1Zi5lwGZg9ZeZftMby6qkG5tmDVqCJBNEiZpTq9AvyM7rgIN50wutP7By+Lhl/g0 D0Z3LIeDqM51ly9B0BdB+a0Q35GLE0ZnUe0RL9sY3wo9ygLLeTZrNpS7YdEUaURz43E6 S3NQ== X-Gm-Message-State: AOAM531mocgrFk1dItxM8QA56BJTbmfEdJjCwzp0xzI37JEZbQGeApMI Wg87BrNxuXemDhmoyc/9oszHrg== X-Google-Smtp-Source: ABdhPJxCDceYWRati28gRyR2MZg5jIN0/VdJ4+0q1+AusUpULOSN9NiaiWRtWjYKJucbY9Swc+dQTw== X-Received: by 2002:a17:90a:2947:: with SMTP id x7mr11321170pjf.157.1611227934689; Thu, 21 Jan 2021 03:18:54 -0800 (PST) Received: from localhost ([122.172.59.240]) by smtp.gmail.com with ESMTPSA id g5sm5980697pfb.194.2021.01.21.03.18.53 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 21 Jan 2021 03:18:54 -0800 (PST) From: Viresh Kumar To: Dmitry Osipenko , Viresh Kumar , Nishanth Menon , Stephen Boyd Subject: [PATCH 04/13] opp: Split _set_opp() out of dev_pm_opp_set_rate() Date: Thu, 21 Jan 2021 16:47:44 +0530 Message-Id: X-Mailer: git-send-email 2.25.0.rc1.19.g042ed3e048af In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210121_061857_214334_6B34D25A X-CRM114-Status: GOOD ( 23.72 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Vincent Guittot , linux-pm@vger.kernel.org, Viresh Kumar , Rafael Wysocki , linux-kernel@vger.kernel.org, Sibi Sankar , linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The _set_opp() helper will be used for devices which don't change their frequency (like power domains, etc.) later on, prepare for that by breaking the generic part out of dev_pm_opp_set_rate(). Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 126 +++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 55 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 4ee598344e6a..5313dc322bdd 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -992,72 +992,27 @@ static int _disable_opp_table(struct device *dev, struct opp_table *opp_table) return ret; } -/** - * dev_pm_opp_set_rate() - Configure new OPP based on frequency - * @dev: device for which we do this operation - * @target_freq: frequency to achieve - * - * This configures the power-supplies to the levels specified by the OPP - * corresponding to the target_freq, and programs the clock to a value <= - * target_freq, as rounded by clk_round_rate(). Device wanting to run at fmax - * provided by the opp, should have already rounded to the target OPP's - * frequency. - */ -int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) +static int _set_opp(struct device *dev, struct opp_table *opp_table, + struct dev_pm_opp *opp, unsigned long freq) { - struct opp_table *opp_table; - unsigned long freq, old_freq, temp_freq; - struct dev_pm_opp *old_opp, *opp; + struct dev_pm_opp *old_opp; + unsigned long old_freq; int ret; - opp_table = _find_opp_table(dev); - if (IS_ERR(opp_table)) { - dev_err(dev, "%s: device opp doesn't exist\n", __func__); - return PTR_ERR(opp_table); - } - - if (unlikely(!target_freq)) { - ret = _disable_opp_table(dev, opp_table); - goto put_opp_table; - } - - freq = clk_round_rate(opp_table->clk, target_freq); - if ((long)freq <= 0) - freq = target_freq; - - /* - * For IO devices which require an OPP on some platforms/SoCs - * while just needing to scale the clock on some others - * we look for empty OPP tables with just a clock handle and - * scale only the clk. This makes dev_pm_opp_set_rate() - * equivalent to a clk_set_rate() - */ - if (!_get_opp_count(opp_table)) { - ret = _generic_set_opp_clk_only(dev, opp_table->clk, freq); - goto put_opp_table; - } + if (unlikely(!opp)) + return _disable_opp_table(dev, opp_table); /* Find the currently set OPP if we don't know already */ if (unlikely(!opp_table->current_opp)) _find_current_opp(dev, opp_table); - temp_freq = freq; - opp = _find_freq_ceil(opp_table, &temp_freq); - if (IS_ERR(opp)) { - ret = PTR_ERR(opp); - dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", - __func__, freq, ret); - goto put_opp_table; - } - old_opp = opp_table->current_opp; old_freq = old_opp->rate; /* Return early if nothing to do */ if (opp_table->enabled && old_opp == opp) { dev_dbg(dev, "%s: OPPs are same, nothing to do\n", __func__); - ret = 0; - goto put_opp; + return 0; } dev_dbg(dev, "%s: switching OPP: %lu Hz --> %lu Hz\n", __func__, @@ -1067,7 +1022,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) if (freq >= old_freq) { ret = _set_required_opps(dev, opp_table, opp, true); if (ret) - goto put_opp; + return ret; } if (opp_table->set_opp) { @@ -1101,8 +1056,69 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) } } -put_opp: - dev_pm_opp_put(opp); + return ret; +} + +/** + * dev_pm_opp_set_rate() - Configure new OPP based on frequency + * @dev: device for which we do this operation + * @target_freq: frequency to achieve + * + * This configures the power-supplies to the levels specified by the OPP + * corresponding to the target_freq, and programs the clock to a value <= + * target_freq, as rounded by clk_round_rate(). Device wanting to run at fmax + * provided by the opp, should have already rounded to the target OPP's + * frequency. + */ +int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) +{ + struct opp_table *opp_table; + unsigned long freq = 0, temp_freq; + struct dev_pm_opp *opp = NULL; + int ret; + + opp_table = _find_opp_table(dev); + if (IS_ERR(opp_table)) { + dev_err(dev, "%s: device's opp table doesn't exist\n", __func__); + return PTR_ERR(opp_table); + } + + if (target_freq) { + /* + * For IO devices which require an OPP on some platforms/SoCs + * while just needing to scale the clock on some others + * we look for empty OPP tables with just a clock handle and + * scale only the clk. This makes dev_pm_opp_set_rate() + * equivalent to a clk_set_rate() + */ + if (!_get_opp_count(opp_table)) { + ret = _generic_set_opp_clk_only(dev, opp_table->clk, target_freq); + goto put_opp_table; + } + + freq = clk_round_rate(opp_table->clk, target_freq); + if ((long)freq <= 0) + freq = target_freq; + + /* + * The clock driver may support finer resolution of the + * frequencies than the OPP table, don't update the frequency we + * pass to clk_set_rate() here. + */ + temp_freq = freq; + opp = _find_freq_ceil(opp_table, &temp_freq); + if (IS_ERR(opp)) { + ret = PTR_ERR(opp); + dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", + __func__, freq, ret); + goto put_opp_table; + } + } + + ret = _set_opp(dev, opp_table, opp, freq); + + if (opp) + dev_pm_opp_put(opp); put_opp_table: dev_pm_opp_put_opp_table(opp_table); return ret;