Unverified Commit d43eef53 authored by Mark Brown's avatar Mark Brown
Browse files

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.
parents a4ca0245 8856eafc
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -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.
+4 −13
Original line number Diff line number Diff line
@@ -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)
+4 −0
Original line number Diff line number Diff line
@@ -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) {}