Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 59684c87 authored by Cristian Marussi's avatar Cristian Marussi Committed by Greg Kroah-Hartman
Browse files

firmware: arm_scmi: Add SCMI PM driver remove routine

[ Upstream commit dea796fcab0a219830831c070b8dc367d7e0f708 ]

Currently, when removing the SCMI PM driver not all the resources
registered with genpd subsystem are properly de-registered.

As a side effect of this after a driver unload/load cycle you get a
splat with a few warnings like this:

 | debugfs: Directory 'BIG_CPU0' with parent 'pm_genpd' already present!
 | debugfs: Directory 'BIG_CPU1' with parent 'pm_genpd' already present!
 | debugfs: Directory 'LITTLE_CPU0' with parent 'pm_genpd' already present!
 | debugfs: Directory 'LITTLE_CPU1' with parent 'pm_genpd' already present!
 | debugfs: Directory 'LITTLE_CPU2' with parent 'pm_genpd' already present!
 | debugfs: Directory 'LITTLE_CPU3' with parent 'pm_genpd' already present!
 | debugfs: Directory 'BIG_SSTOP' with parent 'pm_genpd' already present!
 | debugfs: Directory 'LITTLE_SSTOP' with parent 'pm_genpd' already present!
 | debugfs: Directory 'DBGSYS' with parent 'pm_genpd' already present!
 | debugfs: Directory 'GPUTOP' with parent 'pm_genpd' already present!

Add a proper scmi_pm_domain_remove callback to the driver in order to
take care of all the needed cleanups not handled by devres framework.

Link: https://lore.kernel.org/r/20220817172731.1185305-7-cristian.marussi@arm.com


Signed-off-by: default avatarCristian Marussi <cristian.marussi@arm.com>
Signed-off-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 70e4f70d
Loading
Loading
Loading
Loading
+20 −0
Original line number Original line Diff line number Diff line
@@ -106,9 +106,28 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
	scmi_pd_data->domains = domains;
	scmi_pd_data->domains = domains;
	scmi_pd_data->num_domains = num_domains;
	scmi_pd_data->num_domains = num_domains;


	dev_set_drvdata(dev, scmi_pd_data);

	return of_genpd_add_provider_onecell(np, scmi_pd_data);
	return of_genpd_add_provider_onecell(np, scmi_pd_data);
}
}


static void scmi_pm_domain_remove(struct scmi_device *sdev)
{
	int i;
	struct genpd_onecell_data *scmi_pd_data;
	struct device *dev = &sdev->dev;
	struct device_node *np = dev->of_node;

	of_genpd_del_provider(np);

	scmi_pd_data = dev_get_drvdata(dev);
	for (i = 0; i < scmi_pd_data->num_domains; i++) {
		if (!scmi_pd_data->domains[i])
			continue;
		pm_genpd_remove(scmi_pd_data->domains[i]);
	}
}

static const struct scmi_device_id scmi_id_table[] = {
static const struct scmi_device_id scmi_id_table[] = {
	{ SCMI_PROTOCOL_POWER },
	{ SCMI_PROTOCOL_POWER },
	{ },
	{ },
@@ -118,6 +137,7 @@ MODULE_DEVICE_TABLE(scmi, scmi_id_table);
static struct scmi_driver scmi_power_domain_driver = {
static struct scmi_driver scmi_power_domain_driver = {
	.name = "scmi-power-domain",
	.name = "scmi-power-domain",
	.probe = scmi_pm_domain_probe,
	.probe = scmi_pm_domain_probe,
	.remove = scmi_pm_domain_remove,
	.id_table = scmi_id_table,
	.id_table = scmi_id_table,
};
};
module_scmi_driver(scmi_power_domain_driver);
module_scmi_driver(scmi_power_domain_driver);