of.c (db6da59cf27b5661ced03754ae0550f8914eda9e) of.c (84cb7ff35fcf7c0b552f553a3f2db9c3e92fc707)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Generic OPP OF helpers
4 *
5 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
6 * Nishanth Menon
7 * Romit Dasgupta
8 * Kevin Hilman

--- 7 unchanged lines hidden (view full) ---

16#include <linux/of.h>
17#include <linux/pm_domain.h>
18#include <linux/slab.h>
19#include <linux/export.h>
20#include <linux/energy_model.h>
21
22#include "opp.h"
23
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Generic OPP OF helpers
4 *
5 * Copyright (C) 2009-2010 Texas Instruments Incorporated.
6 * Nishanth Menon
7 * Romit Dasgupta
8 * Kevin Hilman

--- 7 unchanged lines hidden (view full) ---

16#include <linux/of.h>
17#include <linux/pm_domain.h>
18#include <linux/slab.h>
19#include <linux/export.h>
20#include <linux/energy_model.h>
21
22#include "opp.h"
23
24/* OPP tables with uninitialized required OPPs, protected by opp_table_lock */
25static LIST_HEAD(lazy_opp_tables);
26
24/*
25 * Returns opp descriptor node for a device node, caller must
26 * do of_node_put().
27 */
28static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np,
29 int index)
30{
31 /* "operating-points-v2" can be an array for power domain providers */

--- 108 unchanged lines hidden (view full) ---

140
141 dev_pm_opp_put_opp_table(required_opp_tables[i]);
142 }
143
144 kfree(required_opp_tables);
145
146 opp_table->required_opp_count = 0;
147 opp_table->required_opp_tables = NULL;
27/*
28 * Returns opp descriptor node for a device node, caller must
29 * do of_node_put().
30 */
31static struct device_node *_opp_of_get_opp_desc_node(struct device_node *np,
32 int index)
33{
34 /* "operating-points-v2" can be an array for power domain providers */

--- 108 unchanged lines hidden (view full) ---

143
144 dev_pm_opp_put_opp_table(required_opp_tables[i]);
145 }
146
147 kfree(required_opp_tables);
148
149 opp_table->required_opp_count = 0;
150 opp_table->required_opp_tables = NULL;
151
152 mutex_lock(&opp_table_lock);
148 list_del(&opp_table->lazy);
153 list_del(&opp_table->lazy);
154 mutex_unlock(&opp_table_lock);
149}
150
151/*
152 * Populate all devices and opp tables which are part of "required-opps" list.
153 * Checking only the first OPP node should be enough.
154 */
155static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
156 struct device *dev,

--- 32 unchanged lines hidden (view full) ---

189 required_opp_tables[i] = _find_table_of_opp_np(required_np);
190 of_node_put(required_np);
191
192 if (IS_ERR(required_opp_tables[i]))
193 lazy = true;
194 }
195
196 /* Let's do the linking later on */
155}
156
157/*
158 * Populate all devices and opp tables which are part of "required-opps" list.
159 * Checking only the first OPP node should be enough.
160 */
161static void _opp_table_alloc_required_tables(struct opp_table *opp_table,
162 struct device *dev,

--- 32 unchanged lines hidden (view full) ---

195 required_opp_tables[i] = _find_table_of_opp_np(required_np);
196 of_node_put(required_np);
197
198 if (IS_ERR(required_opp_tables[i]))
199 lazy = true;
200 }
201
202 /* Let's do the linking later on */
197 if (lazy)
203 if (lazy) {
204 /*
205 * The OPP table is not held while allocating the table, take it
206 * now to avoid corruption to the lazy_opp_tables list.
207 */
208 mutex_lock(&opp_table_lock);
198 list_add(&opp_table->lazy, &lazy_opp_tables);
209 list_add(&opp_table->lazy, &lazy_opp_tables);
210 mutex_unlock(&opp_table_lock);
211 }
199 else
200 _update_set_required_opps(opp_table);
201
202 goto put_np;
203
204free_required_tables:
205 _opp_table_free_required_tables(opp_table);
206put_np:

--- 809 unchanged lines hidden (view full) ---

1016
1017 /* There should be one or more OPPs defined */
1018 if (!count) {
1019 dev_err(dev, "%s: no supported OPPs", __func__);
1020 ret = -ENOENT;
1021 goto remove_static_opp;
1022 }
1023
212 else
213 _update_set_required_opps(opp_table);
214
215 goto put_np;
216
217free_required_tables:
218 _opp_table_free_required_tables(opp_table);
219put_np:

--- 809 unchanged lines hidden (view full) ---

1029
1030 /* There should be one or more OPPs defined */
1031 if (!count) {
1032 dev_err(dev, "%s: no supported OPPs", __func__);
1033 ret = -ENOENT;
1034 goto remove_static_opp;
1035 }
1036
1024 list_for_each_entry(opp, &opp_table->opp_list, node) {
1025 /* Any non-zero performance state would enable the feature */
1026 if (opp->pstate) {
1027 opp_table->genpd_performance_state = true;
1028 break;
1029 }
1030 }
1031
1032 lazy_link_required_opp_table(opp_table);
1033
1034 return 0;
1035
1036remove_static_opp:
1037 _opp_remove_all_static(opp_table);
1038
1039 return ret;

--- 342 unchanged lines hidden (view full) ---

1382
1383 opp_table = _find_table_of_opp_np(required_np);
1384 if (IS_ERR(opp_table)) {
1385 pr_err("%s: Failed to find required OPP table %pOF: %ld\n",
1386 __func__, np, PTR_ERR(opp_table));
1387 goto put_required_np;
1388 }
1389
1037 lazy_link_required_opp_table(opp_table);
1038
1039 return 0;
1040
1041remove_static_opp:
1042 _opp_remove_all_static(opp_table);
1043
1044 return ret;

--- 342 unchanged lines hidden (view full) ---

1387
1388 opp_table = _find_table_of_opp_np(required_np);
1389 if (IS_ERR(opp_table)) {
1390 pr_err("%s: Failed to find required OPP table %pOF: %ld\n",
1391 __func__, np, PTR_ERR(opp_table));
1392 goto put_required_np;
1393 }
1394
1395 /* The OPP tables must belong to a genpd */
1396 if (unlikely(!opp_table->is_genpd)) {
1397 pr_err("%s: Performance state is only valid for genpds.\n", __func__);
1398 goto put_required_np;
1399 }
1400
1390 opp = _find_opp_of_np(opp_table, required_np);
1391 if (opp) {
1392 pstate = opp->pstate;
1393 dev_pm_opp_put(opp);
1394 }
1395
1396 dev_pm_opp_put_opp_table(opp_table);
1397

--- 197 unchanged lines hidden ---
1401 opp = _find_opp_of_np(opp_table, required_np);
1402 if (opp) {
1403 pstate = opp->pstate;
1404 dev_pm_opp_put(opp);
1405 }
1406
1407 dev_pm_opp_put_opp_table(opp_table);
1408

--- 197 unchanged lines hidden ---