summaryrefslogtreecommitdiff
path: root/drivers/mfd/cs42l43.c
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.cirrus.com>2024-12-05 11:58:22 +0000
committerLee Jones <lee@kernel.org>2024-12-17 13:17:25 +0000
commit0f35dc4bd50df4ad3c17a2c53cdccc4cdc5caa9e (patch)
treecb498bb90a45adebf8914aca2c81def4d6164a78 /drivers/mfd/cs42l43.c
parent47dde1a077dcdcd5b9071983a11ec34cf302b943 (diff)
mfd: cs42l43: Use devres for remove as well
Currently the device is powered down in the remove callback, however all other clean up is done through devres. The problem here is the MFD children are cleaned up through devres. As this happens after the remove callback has run, this leads to the incorrect ordering where the child remove functions run after the device has been powered down. Put the power down into devres as well such that everything runs in the expected order. Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20241205115822.2371719-4-ckeepax@opensource.cirrus.com Signed-off-by: Lee Jones <lee@kernel.org>
Diffstat (limited to 'drivers/mfd/cs42l43.c')
-rw-r--r--drivers/mfd/cs42l43.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c
index 9572c7fd419a..beb63c4efd21 100644
--- a/drivers/mfd/cs42l43.c
+++ b/drivers/mfd/cs42l43.c
@@ -1038,6 +1038,15 @@ static int cs42l43_power_down(struct cs42l43 *cs42l43)
return 0;
}
+static void cs42l43_dev_remove(void *data)
+{
+ struct cs42l43 *cs42l43 = data;
+
+ cancel_work_sync(&cs42l43->boot_work);
+
+ cs42l43_power_down(cs42l43);
+}
+
int cs42l43_dev_probe(struct cs42l43 *cs42l43)
{
int i, ret;
@@ -1084,6 +1093,10 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
if (ret)
return ret;
+ ret = devm_add_action_or_reset(cs42l43->dev, cs42l43_dev_remove, cs42l43);
+ if (ret)
+ return ret;
+
pm_runtime_set_autosuspend_delay(cs42l43->dev, CS42L43_AUTOSUSPEND_TIME_MS);
pm_runtime_use_autosuspend(cs42l43->dev);
pm_runtime_set_active(cs42l43->dev);
@@ -1102,14 +1115,6 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
}
EXPORT_SYMBOL_NS_GPL(cs42l43_dev_probe, MFD_CS42L43);
-void cs42l43_dev_remove(struct cs42l43 *cs42l43)
-{
- cancel_work_sync(&cs42l43->boot_work);
-
- cs42l43_power_down(cs42l43);
-}
-EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, MFD_CS42L43);
-
static int cs42l43_suspend(struct device *dev)
{
struct cs42l43 *cs42l43 = dev_get_drvdata(dev);