mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 18:43:33 +02:00
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:
commit
d43eef5309
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user