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: Daniel Lezcano <daniel.lezcano@linaro.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20220130210210.549877-4-daniel.lezcano@linaro.org
This commit is contained in:
parent
690de0b401
commit
c404c64d64
|
@ -617,3 +617,46 @@ out_unlock:
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue