static void lazy_link_required_opp_table()

in of.c [354:416]


static void lazy_link_required_opp_table(struct opp_table *new_table)
{
	struct opp_table *opp_table, *temp, **required_opp_tables;
	struct device_node *required_np, *opp_np, *required_table_np;
	struct dev_pm_opp *opp;
	int i, ret;

	mutex_lock(&opp_table_lock);

	list_for_each_entry_safe(opp_table, temp, &lazy_opp_tables, lazy) {
		bool lazy = false;

		/* opp_np can't be invalid here */
		opp_np = of_get_next_available_child(opp_table->np, NULL);

		for (i = 0; i < opp_table->required_opp_count; i++) {
			required_opp_tables = opp_table->required_opp_tables;

			/* Required opp-table is already parsed */
			if (!IS_ERR(required_opp_tables[i]))
				continue;

			/* required_np can't be invalid here */
			required_np = of_parse_required_opp(opp_np, i);
			required_table_np = of_get_parent(required_np);

			of_node_put(required_table_np);
			of_node_put(required_np);

			/*
			 * Newly added table isn't the required opp-table for
			 * opp_table.
			 */
			if (required_table_np != new_table->np) {
				lazy = true;
				continue;
			}

			required_opp_tables[i] = new_table;
			_get_opp_table_kref(new_table);

			/* Link OPPs now */
			ret = lazy_link_required_opps(opp_table, new_table, i);
			if (ret) {
				/* The OPPs will be marked unusable */
				lazy = false;
				break;
			}
		}

		of_node_put(opp_np);

		/* All required opp-tables found, remove from lazy list */
		if (!lazy) {
			list_del_init(&opp_table->lazy);

			list_for_each_entry(opp, &opp_table->opp_list, node)
				_required_opps_available(opp, opp_table->required_opp_count);
		}
	}

	mutex_unlock(&opp_table_lock);
}