mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
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>
This commit is contained in:
parent
47dde1a077
commit
0f35dc4bd5
@ -56,13 +56,6 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
|
||||
return cs42l43_dev_probe(cs42l43);
|
||||
}
|
||||
|
||||
static void cs42l43_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(&i2c->dev);
|
||||
|
||||
cs42l43_dev_remove(cs42l43);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
static const struct of_device_id cs42l43_of_match[] = {
|
||||
{ .compatible = "cirrus,cs42l43", },
|
||||
@ -88,7 +81,6 @@ static struct i2c_driver cs42l43_i2c_driver = {
|
||||
},
|
||||
|
||||
.probe = cs42l43_i2c_probe,
|
||||
.remove = cs42l43_i2c_remove,
|
||||
};
|
||||
module_i2c_driver(cs42l43_i2c_driver);
|
||||
|
||||
|
@ -187,15 +187,6 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
|
||||
return cs42l43_dev_probe(cs42l43);
|
||||
}
|
||||
|
||||
static int cs42l43_sdw_remove(struct sdw_slave *sdw)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev);
|
||||
|
||||
cs42l43_dev_remove(cs42l43);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sdw_device_id cs42l43_sdw_id[] = {
|
||||
SDW_SLAVE_ENTRY(0x01FA, 0x4243, 0),
|
||||
{}
|
||||
@ -209,7 +200,6 @@ static struct sdw_driver cs42l43_sdw_driver = {
|
||||
},
|
||||
|
||||
.probe = cs42l43_sdw_probe,
|
||||
.remove = cs42l43_sdw_remove,
|
||||
.id_table = cs42l43_sdw_id,
|
||||
.ops = &cs42l43_sdw_ops,
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -25,6 +25,5 @@ bool cs42l43_precious_register(struct device *dev, unsigned int reg);
|
||||
bool cs42l43_volatile_register(struct device *dev, unsigned int reg);
|
||||
|
||||
int cs42l43_dev_probe(struct cs42l43 *cs42l43);
|
||||
void cs42l43_dev_remove(struct cs42l43 *cs42l43);
|
||||
|
||||
#endif /* CS42L43_CORE_INT_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user