From nobody Mon Feb 9 16:33:17 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A1A523C390 for ; Thu, 24 Apr 2025 10:37:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745491043; cv=none; b=Qjmg9+hyAyK56AKGBxuEzzH2KKnS/R4sueJ9P4w7N+tzYZkeDDidIRf7nyFmbqf59vSu75jXchOmfET9pdKkL6zERKQU3vWspI1dq2ucVovgFOySE1YIj+3BAZp3/wrsJwgEyiHMKw/E8uPw7HrMhN5wK8IqwZ6ihSBJ1utrBIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745491043; c=relaxed/simple; bh=UIhihO+KSlk84fI+BFSWcB1XVu68h01gI8MX+i/A85Q=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gHJsVvnrYPKzgFZzXFZqQHFzyXDDdy7SetcdmPe2Tyz+ti5u++AzEoTdJubbfR9VJGCLSSVFc7cVaaKnFZsG0CyYVPIsMr4qQLBgcIc54D3kyNxQkHObFeLtrqoNtRfPN7NqH/3N9tWUb3ieHICD3vm8YY2kKnp+AmJtM8zC0GY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=hwZy63hQ; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="hwZy63hQ" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-22c3407a87aso13199655ad.3 for ; Thu, 24 Apr 2025 03:37:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1745491040; x=1746095840; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lWVroK7uqi5IEJnUfPHoEkoDsKi7RyYwEa+CnjAgxus=; b=hwZy63hQZwUT9lz37EC6GjOLUpya01qRTYkk46zXD06Q3Q50kZ8WGvO6BqmWOPM1Qx UA7kTXW2Rc/T0Isny2VbZFVh3mob2oR5jdLgoNkd2PyxtFCYV4ReSImVFpeM5nEOR7YK qOjw2+5N86grqWJvjeNUlPvrTbVnslZmqagy4EFp7N1HE8wDwBAQs6SeJRcqQn6LItSj X0WGcLs511d/8dKtgX4NmbWbRHcC4wlpIVx63iyKyBYBPCPxOLCxgH/RRgT8ubD0jm9f RmohfKPbv67N33IsuREynPz5JxYFQi77snXJgsr3d1XXum7vCNJ1MkTsj5Bv9HAqE4Uf gqKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745491040; x=1746095840; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lWVroK7uqi5IEJnUfPHoEkoDsKi7RyYwEa+CnjAgxus=; b=Cn7a3pwdfhDFXQu4N7nBR/iO1U+3Uxx86l66BYmu+kVeVJlkzykspNoZ8XVORV0lzb Q2aJKlTGLwjA9xJy1bUE34zZ4P6BmDSTIDInCI1rd4TgA5MZDMa4BGYZcOWie5HJJt88 n+m8HpIeNW4n1zxm4EKEj39H6iM1jsBaq4zQ5eNMIm4HNTUFj+jNNpgVtMDskMYuMf2o O4yW2XVEw6gbRYJK62CZZFETpjBPDH20i2aC2r7qM+zVCkEo45k0hUx/UIfzWVg3ymmY T1NeDusJ26e4nL079VPFH82nghdJBr68sSj1GUGVWGj097wHcCsOtoBByvlPI0RWIvpq 6gWg== X-Forwarded-Encrypted: i=1; AJvYcCVR2RLBBweuSP0AEuWKlW+h+zgl9mB/AH208zqBCO4fMOt0M6LNIHpcQZ0knBiSHlRiG3ZxzW74Bc/uHRs=@vger.kernel.org X-Gm-Message-State: AOJu0Yyf/ZT0gcbRauGSAsCYNwslG4dvGdbX/MZ9RaCGzTZCyS2kqkx2 tH0wzl3uZsxL2u5R7KjP+GKMzTojRba8/xRDRnKF16QNpE5Wqg3b4F6Z1C0/PmE= X-Gm-Gg: ASbGncsK/+tfv8uUT99KmDj7d9IMO9A0xwifHhZyUZCNLWRjxB37ZQaWJgUEct9eAFG cxB8wTANbWvlK0GgUKOUqiMSLSJXCeTAPdVnVgjEJaQmry32WC5KpjBC6E64yLbqbokVa/KBBE2 vGj/H5kOFH6785PZ/cYdGDqLDq1uYUuSXmK+Vhp2/9GnG5NokVhsEWyShpJrWkdujAt2t9Rhvrr JtHlT4XrUPF7GWUqVVq2MxMlJu6Oyx6heWaZUZfnwhSKXlvKAo7XRd2IGZD+jnRqrGpJgB9cgTc ti1SuUX2bRMt0tpq8hZM1fbw4hMZFjeBoqw66VoXsg== X-Google-Smtp-Source: AGHT+IFtkyIv19VH4ZqdUc9coJM/UdcvKr/acvdXxMY9KrQZhZFnapOrBvqfiYotRgy3+oauDgRFTA== X-Received: by 2002:a17:903:24a:b0:223:668d:eba9 with SMTP id d9443c01a7336-22db3bb6f7dmr33678345ad.10.1745491040511; Thu, 24 Apr 2025 03:37:20 -0700 (PDT) Received: from localhost ([122.172.83.32]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b15f76f582csm908421a12.4.2025.04.24.03.37.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Apr 2025 03:37:20 -0700 (PDT) From: Viresh Kumar To: 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/6] OPP: Define and use scope-based cleanup helpers Date: Thu, 24 Apr 2025 16:06:48 +0530 Message-Id: <5330d0dab7367f7e17911dfa82a6712de27aa968.1745490980.git.viresh.kumar@linaro.org> X-Mailer: git-send-email 2.31.1.272.g89b43f80a514 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Define and use scope-based cleanup helpers for `struct opp` and `struct opp_table`. No intentional functional impact. Signed-off-by: Viresh Kumar --- drivers/opp/core.c | 236 ++++++++++++++--------------------------- drivers/opp/cpu.c | 27 ++--- drivers/opp/of.c | 24 ++--- include/linux/pm_opp.h | 7 ++ 4 files changed, 102 insertions(+), 192 deletions(-) diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 14fb0f43cc77..87d27132cd87 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -317,18 +317,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_is_turbo); */ unsigned long dev_pm_opp_get_max_clock_latency(struct device *dev) { - struct opp_table *opp_table; - unsigned long clock_latency_ns; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) return 0; =20 - clock_latency_ns =3D opp_table->clock_latency_ns_max; - - dev_pm_opp_put_opp_table(opp_table); - - return clock_latency_ns; + return opp_table->clock_latency_ns_max; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency); =20 @@ -340,7 +335,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_clock_latency); */ unsigned long dev_pm_opp_get_max_volt_latency(struct device *dev) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); struct dev_pm_opp *opp; struct regulator *reg; unsigned long latency_ns =3D 0; @@ -356,13 +351,13 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct = device *dev) =20 /* Regulator may not be required for the device */ if (!opp_table->regulators) - goto put_opp_table; + return 0; =20 count =3D opp_table->regulator_count; =20 uV =3D kmalloc_array(count, sizeof(*uV), GFP_KERNEL); if (!uV) - goto put_opp_table; + return 0; =20 mutex_lock(&opp_table->lock); =20 @@ -395,8 +390,6 @@ unsigned long dev_pm_opp_get_max_volt_latency(struct de= vice *dev) } =20 kfree(uV); -put_opp_table: - dev_pm_opp_put_opp_table(opp_table); =20 return latency_ns; } @@ -426,7 +419,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_max_transition_latency= ); */ unsigned long dev_pm_opp_get_suspend_opp_freq(struct device *dev) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); unsigned long freq =3D 0; =20 opp_table =3D _find_opp_table(dev); @@ -436,8 +429,6 @@ unsigned long dev_pm_opp_get_suspend_opp_freq(struct de= vice *dev) if (opp_table->suspend_opp && opp_table->suspend_opp->available) freq =3D dev_pm_opp_get_freq(opp_table->suspend_opp); =20 - dev_pm_opp_put_opp_table(opp_table); - return freq; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_suspend_opp_freq); @@ -468,21 +459,16 @@ int _get_opp_count(struct opp_table *opp_table) */ int dev_pm_opp_get_opp_count(struct device *dev) { - struct opp_table *opp_table; - int count; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) { - count =3D PTR_ERR(opp_table); - dev_dbg(dev, "%s: OPP table not found (%d)\n", - __func__, count); - return count; + dev_dbg(dev, "%s: OPP table not found (%ld)\n", + __func__, PTR_ERR(opp_table)); + return PTR_ERR(opp_table); } =20 - count =3D _get_opp_count(opp_table); - dev_pm_opp_put_opp_table(opp_table); - - return count; + return _get_opp_count(opp_table); } EXPORT_SYMBOL_GPL(dev_pm_opp_get_opp_count); =20 @@ -576,8 +562,7 @@ _find_key(struct device *dev, unsigned long *key, int i= ndex, bool available, unsigned long opp_key, unsigned long key), bool (*assert)(struct opp_table *opp_table, unsigned int index)) { - struct opp_table *opp_table; - struct dev_pm_opp *opp; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) { @@ -586,12 +571,8 @@ _find_key(struct device *dev, unsigned long *key, int = index, bool available, return ERR_CAST(opp_table); } =20 - opp =3D _opp_table_find_key(opp_table, key, index, available, read, - compare, assert); - - dev_pm_opp_put_opp_table(opp_table); - - return opp; + return _opp_table_find_key(opp_table, key, index, available, read, + compare, assert); } =20 static struct dev_pm_opp *_find_key_exact(struct device *dev, @@ -1345,11 +1326,10 @@ static int _set_opp(struct device *dev, struct opp_= table *opp_table, */ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); + struct dev_pm_opp *opp __free(put_opp) =3D NULL; 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); if (IS_ERR(opp_table)) { @@ -1366,9 +1346,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 opp_table->config_clks(dev, opp_table, NULL, - &target_freq, false); - goto put_opp_table; + return opp_table->config_clks(dev, opp_table, NULL, + &target_freq, false); } =20 freq =3D clk_round_rate(opp_table->clk, target_freq); @@ -1383,10 +1362,9 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned= long target_freq) temp_freq =3D freq; opp =3D _find_freq_ceil(opp_table, &temp_freq); if (IS_ERR(opp)) { - ret =3D PTR_ERR(opp); - dev_err(dev, "%s: failed to find OPP for freq %lu (%d)\n", - __func__, freq, ret); - goto put_opp_table; + dev_err(dev, "%s: failed to find OPP for freq %lu (%ld)\n", + __func__, freq, PTR_ERR(opp)); + return PTR_ERR(opp); } =20 /* @@ -1399,14 +1377,7 @@ int dev_pm_opp_set_rate(struct device *dev, unsigned= long target_freq) forced =3D opp_table->current_rate_single_clk !=3D freq; } =20 - ret =3D _set_opp(dev, opp_table, opp, &freq, forced); - - if (freq) - dev_pm_opp_put(opp); - -put_opp_table: - dev_pm_opp_put_opp_table(opp_table); - return ret; + return _set_opp(dev, opp_table, opp, &freq, forced); } EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate); =20 @@ -1422,8 +1393,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_rate); */ int dev_pm_opp_set_opp(struct device *dev, struct dev_pm_opp *opp) { - struct opp_table *opp_table; - int ret; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) { @@ -1431,10 +1401,7 @@ int dev_pm_opp_set_opp(struct device *dev, struct de= v_pm_opp *opp) return PTR_ERR(opp_table); } =20 - ret =3D _set_opp(dev, opp_table, opp, NULL, false); - dev_pm_opp_put_opp_table(opp_table); - - return ret; + return _set_opp(dev, opp_table, opp, NULL, false); } EXPORT_SYMBOL_GPL(dev_pm_opp_set_opp); =20 @@ -1744,15 +1711,15 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put); */ void dev_pm_opp_remove(struct device *dev, unsigned long freq) { + struct opp_table *opp_table __free(put_opp_table); struct dev_pm_opp *opp =3D NULL, *iter; - struct opp_table *opp_table; =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) return; =20 if (!assert_single_clk(opp_table, 0)) - goto put_table; + return; =20 mutex_lock(&opp_table->lock); =20 @@ -1774,10 +1741,6 @@ void dev_pm_opp_remove(struct device *dev, unsigned = long freq) dev_warn(dev, "%s: Couldn't find OPP with freq: %lu\n", __func__, freq); } - -put_table: - /* Drop the reference taken by _find_opp_table() */ - dev_pm_opp_put_opp_table(opp_table); } EXPORT_SYMBOL_GPL(dev_pm_opp_remove); =20 @@ -1849,16 +1812,13 @@ bool _opp_remove_all_static(struct opp_table *opp_t= able) */ void dev_pm_opp_remove_all_dynamic(struct device *dev) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) return; =20 _opp_remove_all(opp_table, true); - - /* Drop the reference taken by _find_opp_table() */ - dev_pm_opp_put_opp_table(opp_table); } EXPORT_SYMBOL_GPL(dev_pm_opp_remove_all_dynamic); =20 @@ -2846,47 +2806,43 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_add_dynamic); static int _opp_set_availability(struct device *dev, unsigned long freq, bool availability_req) { - struct opp_table *opp_table; - struct dev_pm_opp *tmp_opp, *opp =3D ERR_PTR(-ENODEV); - int r =3D 0; + struct dev_pm_opp *opp __free(put_opp) =3D ERR_PTR(-ENODEV), *tmp_opp; + struct opp_table *opp_table __free(put_opp_table); =20 /* Find the opp_table */ opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) { - r =3D PTR_ERR(opp_table); - dev_warn(dev, "%s: Device OPP not found (%d)\n", __func__, r); - return r; + dev_warn(dev, "%s: Device OPP not found (%ld)\n", __func__, + PTR_ERR(opp_table)); + return PTR_ERR(opp_table); } =20 - if (!assert_single_clk(opp_table, 0)) { - r =3D -EINVAL; - goto put_table; - } + if (!assert_single_clk(opp_table, 0)) + return -EINVAL; =20 mutex_lock(&opp_table->lock); =20 /* Do we have the frequency? */ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) { if (tmp_opp->rates[0] =3D=3D freq) { - opp =3D tmp_opp; + opp =3D dev_pm_opp_get(tmp_opp); + + /* Is update really needed? */ + if (opp->available =3D=3D availability_req) { + mutex_unlock(&opp_table->lock); + return 0; + } + + opp->available =3D availability_req; break; } } =20 - if (IS_ERR(opp)) { - r =3D PTR_ERR(opp); - goto unlock; - } - - /* Is update really needed? */ - if (opp->available =3D=3D availability_req) - goto unlock; - - opp->available =3D availability_req; - - dev_pm_opp_get(opp); mutex_unlock(&opp_table->lock); =20 + if (IS_ERR(opp)) + return PTR_ERR(opp); + /* Notify the change of the OPP availability */ if (availability_req) blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ENABLE, @@ -2895,14 +2851,7 @@ static int _opp_set_availability(struct device *dev,= unsigned long freq, blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_DISABLE, opp); =20 - dev_pm_opp_put(opp); - goto put_table; - -unlock: - mutex_unlock(&opp_table->lock); -put_table: - dev_pm_opp_put_opp_table(opp_table); - return r; + return 0; } =20 /** @@ -2922,9 +2871,9 @@ int dev_pm_opp_adjust_voltage(struct device *dev, uns= igned long freq, unsigned long u_volt_max) =20 { - struct opp_table *opp_table; - struct dev_pm_opp *tmp_opp, *opp =3D ERR_PTR(-ENODEV); - int r =3D 0; + struct dev_pm_opp *opp __free(put_opp) =3D ERR_PTR(-ENODEV), *tmp_opp; + struct opp_table *opp_table __free(put_opp_table); + int r; =20 /* Find the opp_table */ opp_table =3D _find_opp_table(dev); @@ -2934,49 +2883,40 @@ int dev_pm_opp_adjust_voltage(struct device *dev, u= nsigned long freq, return r; } =20 - if (!assert_single_clk(opp_table, 0)) { - r =3D -EINVAL; - goto put_table; - } + if (!assert_single_clk(opp_table, 0)) + return -EINVAL; =20 mutex_lock(&opp_table->lock); =20 /* Do we have the frequency? */ list_for_each_entry(tmp_opp, &opp_table->opp_list, node) { if (tmp_opp->rates[0] =3D=3D freq) { - opp =3D tmp_opp; - break; - } - } + opp =3D dev_pm_opp_get(tmp_opp); =20 - if (IS_ERR(opp)) { - r =3D PTR_ERR(opp); - goto adjust_unlock; - } + /* Is update really needed? */ + if (opp->supplies->u_volt =3D=3D u_volt) { + mutex_unlock(&opp_table->lock); + return 0; + } =20 - /* Is update really needed? */ - if (opp->supplies->u_volt =3D=3D u_volt) - goto adjust_unlock; + opp->supplies->u_volt =3D u_volt; + opp->supplies->u_volt_min =3D u_volt_min; + opp->supplies->u_volt_max =3D u_volt_max; =20 - opp->supplies->u_volt =3D u_volt; - opp->supplies->u_volt_min =3D u_volt_min; - opp->supplies->u_volt_max =3D u_volt_max; + break; + } + } =20 - dev_pm_opp_get(opp); mutex_unlock(&opp_table->lock); =20 + if (IS_ERR(opp)) + return PTR_ERR(opp); + /* Notify the voltage change of the OPP */ blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_ADJUST_VOLTAGE, opp); =20 - dev_pm_opp_put(opp); - goto put_table; - -adjust_unlock: - mutex_unlock(&opp_table->lock); -put_table: - dev_pm_opp_put_opp_table(opp_table); - return r; + return 0; } EXPORT_SYMBOL_GPL(dev_pm_opp_adjust_voltage); =20 @@ -2990,9 +2930,9 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_adjust_voltage); */ int dev_pm_opp_sync_regulators(struct device *dev) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); struct regulator *reg; - int i, ret =3D 0; + int i; =20 /* Device may not have OPP table */ opp_table =3D _find_opp_table(dev); @@ -3001,23 +2941,18 @@ int dev_pm_opp_sync_regulators(struct device *dev) =20 /* Regulator may not be required for the device */ if (unlikely(!opp_table->regulators)) - goto put_table; + return 0; =20 /* Nothing to sync if voltage wasn't changed */ if (!opp_table->enabled) - goto put_table; + return 0; =20 for (i =3D 0; i < opp_table->regulator_count; i++) { reg =3D opp_table->regulators[i]; - ret =3D regulator_sync_voltage(reg); - if (ret) - break; + return regulator_sync_voltage(reg); } -put_table: - /* Drop reference taken by _find_opp_table() */ - dev_pm_opp_put_opp_table(opp_table); =20 - return ret; + return 0; } EXPORT_SYMBOL_GPL(dev_pm_opp_sync_regulators); =20 @@ -3069,18 +3004,13 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_disable); */ int dev_pm_opp_register_notifier(struct device *dev, struct notifier_block= *nb) { - struct opp_table *opp_table; - int ret; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) return PTR_ERR(opp_table); =20 - ret =3D blocking_notifier_chain_register(&opp_table->head, nb); - - dev_pm_opp_put_opp_table(opp_table); - - return ret; + return blocking_notifier_chain_register(&opp_table->head, nb); } EXPORT_SYMBOL(dev_pm_opp_register_notifier); =20 @@ -3094,18 +3024,13 @@ EXPORT_SYMBOL(dev_pm_opp_register_notifier); int dev_pm_opp_unregister_notifier(struct device *dev, struct notifier_block *nb) { - struct opp_table *opp_table; - int ret; + struct opp_table *opp_table __free(put_opp_table); =20 opp_table =3D _find_opp_table(dev); if (IS_ERR(opp_table)) return PTR_ERR(opp_table); =20 - ret =3D blocking_notifier_chain_unregister(&opp_table->head, nb); - - dev_pm_opp_put_opp_table(opp_table); - - return ret; + return blocking_notifier_chain_unregister(&opp_table->head, nb); } EXPORT_SYMBOL(dev_pm_opp_unregister_notifier); =20 @@ -3118,7 +3043,7 @@ EXPORT_SYMBOL(dev_pm_opp_unregister_notifier); */ void dev_pm_opp_remove_table(struct device *dev) { - struct opp_table *opp_table; + struct opp_table *opp_table __free(put_opp_table); =20 /* Check for existing table for 'dev' */ opp_table =3D _find_opp_table(dev); @@ -3139,8 +3064,5 @@ void dev_pm_opp_remove_table(struct device *dev) **/ if (_opp_remove_all_static(opp_table)) dev_pm_opp_put_opp_table(opp_table); - - /* Drop reference taken by _find_opp_table() */ - dev_pm_opp_put_opp_table(opp_table); } EXPORT_SYMBOL_GPL(dev_pm_opp_remove_table); diff --git a/drivers/opp/cpu.c b/drivers/opp/cpu.c index 12c429b407ca..330a1753fb22 100644 --- a/drivers/opp/cpu.c +++ b/drivers/opp/cpu.c @@ -43,7 +43,6 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, struct cpufreq_frequency_table **opp_table) { - struct dev_pm_opp *opp; struct cpufreq_frequency_table *freq_table =3D NULL; int i, max_opps, ret =3D 0; unsigned long rate; @@ -57,6 +56,8 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, return -ENOMEM; =20 for (i =3D 0, rate =3D 0; i < max_opps; i++, rate++) { + struct dev_pm_opp *opp __free(put_opp); + /* find next rate */ opp =3D dev_pm_opp_find_freq_ceil(dev, &rate); if (IS_ERR(opp)) { @@ -69,8 +70,6 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, /* Is Boost/turbo opp ? */ if (dev_pm_opp_is_turbo(opp)) freq_table[i].flags =3D CPUFREQ_BOOST_FREQ; - - dev_pm_opp_put(opp); } =20 freq_table[i].driver_data =3D i; @@ -155,10 +154,10 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_cpumask_remove_table); int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask) { + struct opp_table *opp_table __free(put_opp_table); struct opp_device *opp_dev; - struct opp_table *opp_table; struct device *dev; - int cpu, ret =3D 0; + int cpu; =20 opp_table =3D _find_opp_table(cpu_dev); if (IS_ERR(opp_table)) @@ -186,9 +185,7 @@ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, opp_table->shared_opp =3D OPP_TABLE_ACCESS_SHARED; } =20 - dev_pm_opp_put_opp_table(opp_table); - - return ret; + return 0; } EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); =20 @@ -204,18 +201,15 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_sharing_cpus); */ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cp= umask) { + struct opp_table *opp_table __free(put_opp_table); struct opp_device *opp_dev; - struct opp_table *opp_table; - int ret =3D 0; =20 opp_table =3D _find_opp_table(cpu_dev); if (IS_ERR(opp_table)) return PTR_ERR(opp_table); =20 - if (opp_table->shared_opp =3D=3D OPP_TABLE_ACCESS_UNKNOWN) { - ret =3D -EINVAL; - goto put_opp_table; - } + if (opp_table->shared_opp =3D=3D OPP_TABLE_ACCESS_UNKNOWN) + return -EINVAL; =20 cpumask_clear(cpumask); =20 @@ -228,9 +222,6 @@ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev,= struct cpumask *cpumask) cpumask_set_cpu(cpu_dev->id, cpumask); } =20 -put_opp_table: - dev_pm_opp_put_opp_table(opp_table); - - return ret; + return 0; } EXPORT_SYMBOL_GPL(dev_pm_opp_get_sharing_cpus); diff --git a/drivers/opp/of.c b/drivers/opp/of.c index aa43fbfa3e50..54109e813d4f 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -1344,8 +1344,8 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_of_get_sharing_cpus); int of_get_required_opp_performance_state(struct device_node *np, int inde= x) { struct device_node *required_np __free(device_node); - struct opp_table *opp_table; - struct dev_pm_opp *opp; + struct opp_table *opp_table __free(put_opp_table) =3D NULL; + struct dev_pm_opp *opp __free(put_opp) =3D NULL; int pstate =3D -EINVAL; =20 required_np =3D of_parse_required_opp(np, index); @@ -1373,11 +1373,8 @@ int of_get_required_opp_performance_state(struct dev= ice_node *np, int index) } else { pstate =3D opp->level; } - dev_pm_opp_put(opp); - } =20 - dev_pm_opp_put_opp_table(opp_table); return pstate; } EXPORT_SYMBOL_GPL(of_get_required_opp_performance_state); @@ -1443,7 +1440,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node); static int __maybe_unused _get_dt_power(struct device *dev, unsigned long *uW, unsigned long *kHz) { - struct dev_pm_opp *opp; + struct dev_pm_opp *opp __free(put_opp); unsigned long opp_freq, opp_power; =20 /* Find the right frequency and related OPP */ @@ -1453,7 +1450,6 @@ _get_dt_power(struct device *dev, unsigned long *uW, = unsigned long *kHz) return -EINVAL; =20 opp_power =3D dev_pm_opp_get_power(opp); - dev_pm_opp_put(opp); if (!opp_power) return -EINVAL; =20 @@ -1484,8 +1480,8 @@ _get_dt_power(struct device *dev, unsigned long *uW, = unsigned long *kHz) int dev_pm_opp_calc_power(struct device *dev, unsigned long *uW, unsigned long *kHz) { + struct dev_pm_opp *opp __free(put_opp) =3D NULL; struct device_node *np __free(device_node); - struct dev_pm_opp *opp; unsigned long mV, Hz; u32 cap; u64 tmp; @@ -1505,7 +1501,6 @@ int dev_pm_opp_calc_power(struct device *dev, unsigne= d long *uW, return -EINVAL; =20 mV =3D dev_pm_opp_get_voltage(opp) / 1000; - dev_pm_opp_put(opp); if (!mV) return -EINVAL; =20 @@ -1522,20 +1517,15 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_calc_power); =20 static bool _of_has_opp_microwatt_property(struct device *dev) { - unsigned long power, freq =3D 0; - struct dev_pm_opp *opp; + struct dev_pm_opp *opp __free(put_opp); + unsigned long freq =3D 0; =20 /* Check if at least one OPP has needed property */ opp =3D dev_pm_opp_find_freq_ceil(dev, &freq); if (IS_ERR(opp)) return false; =20 - power =3D dev_pm_opp_get_power(opp); - dev_pm_opp_put(opp); - if (!power) - return false; - - return true; + return !!dev_pm_opp_get_power(opp); } =20 /** diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h index 0deddfa91aca..e7b5c602c92f 100644 --- a/include/linux/pm_opp.h +++ b/include/linux/pm_opp.h @@ -11,6 +11,7 @@ #ifndef __LINUX_OPP_H__ #define __LINUX_OPP_H__ =20 +#include #include #include #include @@ -710,4 +711,10 @@ static inline unsigned long dev_pm_opp_get_freq(struct= dev_pm_opp *opp) return dev_pm_opp_get_freq_indexed(opp, 0); } =20 +/* Scope based cleanup macro for OPP reference counting */ +DEFINE_FREE(put_opp, struct dev_pm_opp *, if (!IS_ERR_OR_NULL(_T)) dev_pm_= opp_put(_T)) + +/* Scope based cleanup macro for OPP table reference counting */ +DEFINE_FREE(put_opp_table, struct opp_table *, if (!IS_ERR_OR_NULL(_T)) de= v_pm_opp_put_opp_table(_T)) + #endif /* __LINUX_OPP_H__ */ --=20 2.31.1.272.g89b43f80a514