Add more devm_ functions to fix PM imbalance in

Merge series from Bence Csókás <csokas.bence@prolan.hu>:

The probe() function of the atmel-quadspi driver got quite convoluted,
especially since the addition of SAMA7G5 support, that was forward-ported
from an older vendor kernel. During the port, a bug was introduced, where
the PM get() and put() calls were imbalanced. To alleivate this - and
similar problems in the future - an effort was made to migrate as many
functions as possible, to their devm_ managed counterparts. The few
functions, which did not yet have a devm_ variant, are added in patch 1 of
this series. Patch 2 then uses these APIs to fix the probe() function.
This commit is contained in:
Mark Brown 2025-05-12 11:28:54 +09:00
commit d43eef5309
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 52 additions and 13 deletions

View File

@ -1568,6 +1568,32 @@ void pm_runtime_enable(struct device *dev)
}
EXPORT_SYMBOL_GPL(pm_runtime_enable);
static void pm_runtime_set_suspended_action(void *data)
{
pm_runtime_set_suspended(data);
}
/**
* devm_pm_runtime_set_active_enabled - set_active version of devm_pm_runtime_enable.
*
* @dev: Device to handle.
*/
int devm_pm_runtime_set_active_enabled(struct device *dev)
{
int err;
err = pm_runtime_set_active(dev);
if (err)
return err;
err = devm_add_action_or_reset(dev, pm_runtime_set_suspended_action, dev);
if (err)
return err;
return devm_pm_runtime_enable(dev);
}
EXPORT_SYMBOL_GPL(devm_pm_runtime_set_active_enabled);
static void pm_runtime_disable_action(void *data)
{
pm_runtime_dont_use_autosuspend(data);
@ -1590,6 +1616,24 @@ int devm_pm_runtime_enable(struct device *dev)
}
EXPORT_SYMBOL_GPL(devm_pm_runtime_enable);
static void pm_runtime_put_noidle_action(void *data)
{
pm_runtime_put_noidle(data);
}
/**
* devm_pm_runtime_get_noresume - devres-enabled version of pm_runtime_get_noresume.
*
* @dev: Device to handle.
*/
int devm_pm_runtime_get_noresume(struct device *dev)
{
pm_runtime_get_noresume(dev);
return devm_add_action_or_reset(dev, pm_runtime_put_noidle_action, dev);
}
EXPORT_SYMBOL_GPL(devm_pm_runtime_get_noresume);
/**
* pm_runtime_forbid - Block runtime PM of a device.
* @dev: Device to handle.

View File

@ -1437,22 +1437,17 @@ static int atmel_qspi_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
devm_pm_runtime_set_active_enabled(&pdev->dev);
devm_pm_runtime_get_noresume(&pdev->dev);
err = atmel_qspi_init(aq);
if (err)
goto dma_release;
err = spi_register_controller(ctrl);
if (err) {
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
if (err)
goto dma_release;
}
pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
@ -1531,10 +1526,6 @@ static void atmel_qspi_remove(struct platform_device *pdev)
*/
dev_warn(&pdev->dev, "Failed to resume device on remove\n");
}
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_put_noidle(&pdev->dev);
}
static int __maybe_unused atmel_qspi_suspend(struct device *dev)

View File

@ -96,7 +96,9 @@ extern void pm_runtime_new_link(struct device *dev);
extern void pm_runtime_drop_link(struct device_link *link);
extern void pm_runtime_release_supplier(struct device_link *link);
int devm_pm_runtime_set_active_enabled(struct device *dev);
extern int devm_pm_runtime_enable(struct device *dev);
int devm_pm_runtime_get_noresume(struct device *dev);
/**
* pm_suspend_ignore_children - Set runtime PM behavior regarding children.
@ -294,7 +296,9 @@ static inline bool pm_runtime_blocked(struct device *dev) { return true; }
static inline void pm_runtime_allow(struct device *dev) {}
static inline void pm_runtime_forbid(struct device *dev) {}
static inline int devm_pm_runtime_set_active_enabled(struct device *dev) { return 0; }
static inline int devm_pm_runtime_enable(struct device *dev) { return 0; }
static inline int devm_pm_runtime_get_noresume(struct device *dev) { return 0; }
static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
static inline void pm_runtime_get_noresume(struct device *dev) {}