Skip to content

Commit d43eef5

Browse files
committed
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.
2 parents a4ca024 + 8856eaf commit d43eef5

File tree

3 files changed

+52
-13
lines changed

3 files changed

+52
-13
lines changed

drivers/base/power/runtime.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,32 @@ void pm_runtime_enable(struct device *dev)
15681568
}
15691569
EXPORT_SYMBOL_GPL(pm_runtime_enable);
15701570

1571+
static void pm_runtime_set_suspended_action(void *data)
1572+
{
1573+
pm_runtime_set_suspended(data);
1574+
}
1575+
1576+
/**
1577+
* devm_pm_runtime_set_active_enabled - set_active version of devm_pm_runtime_enable.
1578+
*
1579+
* @dev: Device to handle.
1580+
*/
1581+
int devm_pm_runtime_set_active_enabled(struct device *dev)
1582+
{
1583+
int err;
1584+
1585+
err = pm_runtime_set_active(dev);
1586+
if (err)
1587+
return err;
1588+
1589+
err = devm_add_action_or_reset(dev, pm_runtime_set_suspended_action, dev);
1590+
if (err)
1591+
return err;
1592+
1593+
return devm_pm_runtime_enable(dev);
1594+
}
1595+
EXPORT_SYMBOL_GPL(devm_pm_runtime_set_active_enabled);
1596+
15711597
static void pm_runtime_disable_action(void *data)
15721598
{
15731599
pm_runtime_dont_use_autosuspend(data);
@@ -1590,6 +1616,24 @@ int devm_pm_runtime_enable(struct device *dev)
15901616
}
15911617
EXPORT_SYMBOL_GPL(devm_pm_runtime_enable);
15921618

1619+
static void pm_runtime_put_noidle_action(void *data)
1620+
{
1621+
pm_runtime_put_noidle(data);
1622+
}
1623+
1624+
/**
1625+
* devm_pm_runtime_get_noresume - devres-enabled version of pm_runtime_get_noresume.
1626+
*
1627+
* @dev: Device to handle.
1628+
*/
1629+
int devm_pm_runtime_get_noresume(struct device *dev)
1630+
{
1631+
pm_runtime_get_noresume(dev);
1632+
1633+
return devm_add_action_or_reset(dev, pm_runtime_put_noidle_action, dev);
1634+
}
1635+
EXPORT_SYMBOL_GPL(devm_pm_runtime_get_noresume);
1636+
15931637
/**
15941638
* pm_runtime_forbid - Block runtime PM of a device.
15951639
* @dev: Device to handle.

drivers/spi/atmel-quadspi.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,22 +1437,17 @@ static int atmel_qspi_probe(struct platform_device *pdev)
14371437

14381438
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
14391439
pm_runtime_use_autosuspend(&pdev->dev);
1440-
pm_runtime_set_active(&pdev->dev);
1441-
pm_runtime_enable(&pdev->dev);
1442-
pm_runtime_get_noresume(&pdev->dev);
1440+
devm_pm_runtime_set_active_enabled(&pdev->dev);
1441+
devm_pm_runtime_get_noresume(&pdev->dev);
14431442

14441443
err = atmel_qspi_init(aq);
14451444
if (err)
14461445
goto dma_release;
14471446

14481447
err = spi_register_controller(ctrl);
1449-
if (err) {
1450-
pm_runtime_put_noidle(&pdev->dev);
1451-
pm_runtime_disable(&pdev->dev);
1452-
pm_runtime_set_suspended(&pdev->dev);
1453-
pm_runtime_dont_use_autosuspend(&pdev->dev);
1448+
if (err)
14541449
goto dma_release;
1455-
}
1450+
14561451
pm_runtime_mark_last_busy(&pdev->dev);
14571452
pm_runtime_put_autosuspend(&pdev->dev);
14581453

@@ -1531,10 +1526,6 @@ static void atmel_qspi_remove(struct platform_device *pdev)
15311526
*/
15321527
dev_warn(&pdev->dev, "Failed to resume device on remove\n");
15331528
}
1534-
1535-
pm_runtime_disable(&pdev->dev);
1536-
pm_runtime_dont_use_autosuspend(&pdev->dev);
1537-
pm_runtime_put_noidle(&pdev->dev);
15381529
}
15391530

15401531
static int __maybe_unused atmel_qspi_suspend(struct device *dev)

include/linux/pm_runtime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ extern void pm_runtime_new_link(struct device *dev);
9696
extern void pm_runtime_drop_link(struct device_link *link);
9797
extern void pm_runtime_release_supplier(struct device_link *link);
9898

99+
int devm_pm_runtime_set_active_enabled(struct device *dev);
99100
extern int devm_pm_runtime_enable(struct device *dev);
101+
int devm_pm_runtime_get_noresume(struct device *dev);
100102

101103
/**
102104
* 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; }
294296
static inline void pm_runtime_allow(struct device *dev) {}
295297
static inline void pm_runtime_forbid(struct device *dev) {}
296298

299+
static inline int devm_pm_runtime_set_active_enabled(struct device *dev) { return 0; }
297300
static inline int devm_pm_runtime_enable(struct device *dev) { return 0; }
301+
static inline int devm_pm_runtime_get_noresume(struct device *dev) { return 0; }
298302

299303
static inline void pm_suspend_ignore_children(struct device *dev, bool enable) {}
300304
static inline void pm_runtime_get_noresume(struct device *dev) {}

0 commit comments

Comments
 (0)