Commit c404c64d authored by Daniel Lezcano's avatar Daniel Lezcano
Browse files

powercap/dtpm: Destroy hierarchy function



The hierarchy creation function exits but without a destroy hierarchy
function. Due to that, the modules creating the hierarchy can not be
unloaded properly because they don't have an exit callback.

Provide the dtpm_destroy_hierarchy() function to remove the previously
created hierarchy.

The function relies on all the release mechanisms implemented by the
underlying powercap framework.

Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Reviewed-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
Link: https://lore.kernel.org/r/20220130210210.549877-4-daniel.lezcano@linaro.org
parent 690de0b4
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -617,3 +617,46 @@ int dtpm_create_hierarchy(struct of_device_id *dtpm_match_table)
	return ret;
}
EXPORT_SYMBOL_GPL(dtpm_create_hierarchy);

static void __dtpm_destroy_hierarchy(struct dtpm *dtpm)
{
	struct dtpm *child, *aux;

	list_for_each_entry_safe(child, aux, &dtpm->children, sibling)
		__dtpm_destroy_hierarchy(child);

	/*
	 * At this point, we know all children were removed from the
	 * recursive call before
	 */
	dtpm_unregister(dtpm);
}

void dtpm_destroy_hierarchy(void)
{
	int i;

	mutex_lock(&dtpm_lock);

	if (!pct)
		goto out_unlock;

	__dtpm_destroy_hierarchy(root);
	

	for (i = 0; i < ARRAY_SIZE(dtpm_subsys); i++) {

		if (!dtpm_subsys[i]->exit)
			continue;

		dtpm_subsys[i]->exit();
	}

	powercap_unregister_control_type(pct);

	pct = NULL;

out_unlock:
	mutex_unlock(&dtpm_lock);
}
EXPORT_SYMBOL_GPL(dtpm_destroy_hierarchy);
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ struct device_node;
struct dtpm_subsys_ops {
	const char *name;
	int (*init)(void);
	void (*exit)(void);
	int (*setup)(struct dtpm *, struct device_node *);
};

@@ -67,4 +68,6 @@ void dtpm_unregister(struct dtpm *dtpm);
int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent);

int dtpm_create_hierarchy(struct of_device_id *dtpm_match_table);

void dtpm_destroy_hierarchy(void);
#endif