Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ae22e8c authored by Mark Brown's avatar Mark Brown Committed by Rafael J. Wysocki
Browse files

spi / PM: Support dev_pm_ops



Allow SPI drivers to use runtime PM and other dev_pm_ops features by
implementing dev_pm_ops for the bus. The existing bus specific suspend
and resume functions will be called if a driver does not provide dev_pm_ops
allowing for transition to the new model.

Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: default avatarGrant Likely <grant.likely@secretlab.ca>
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
parent 62bcb915
Loading
Loading
Loading
Loading
+84 −8
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/mod_devicetable.h>
#include <linux/mod_devicetable.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi.h>
#include <linux/of_spi.h>
#include <linux/of_spi.h>
#include <linux/pm_runtime.h>


static void spidev_release(struct device *dev)
static void spidev_release(struct device *dev)
{
{
@@ -100,9 +101,8 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
	return 0;
	return 0;
}
}


#ifdef	CONFIG_PM
#ifdef CONFIG_PM_SLEEP

static int spi_legacy_suspend(struct device *dev, pm_message_t message)
static int spi_suspend(struct device *dev, pm_message_t message)
{
{
	int			value = 0;
	int			value = 0;
	struct spi_driver	*drv = to_spi_driver(dev->driver);
	struct spi_driver	*drv = to_spi_driver(dev->driver);
@@ -117,7 +117,7 @@ static int spi_suspend(struct device *dev, pm_message_t message)
	return value;
	return value;
}
}


static int spi_resume(struct device *dev)
static int spi_legacy_resume(struct device *dev)
{
{
	int			value = 0;
	int			value = 0;
	struct spi_driver	*drv = to_spi_driver(dev->driver);
	struct spi_driver	*drv = to_spi_driver(dev->driver);
@@ -132,18 +132,94 @@ static int spi_resume(struct device *dev)
	return value;
	return value;
}
}


static int spi_pm_suspend(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_suspend(dev);
	else
		return spi_legacy_suspend(dev, PMSG_SUSPEND);
}

static int spi_pm_resume(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_resume(dev);
	else
		return spi_legacy_resume(dev);
}

static int spi_pm_freeze(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_freeze(dev);
	else
		return spi_legacy_suspend(dev, PMSG_FREEZE);
}

static int spi_pm_thaw(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_thaw(dev);
	else
		return spi_legacy_resume(dev);
}

static int spi_pm_poweroff(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_poweroff(dev);
	else
		return spi_legacy_suspend(dev, PMSG_HIBERNATE);
}

static int spi_pm_restore(struct device *dev)
{
	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;

	if (pm)
		return pm_generic_restore(dev);
	else
		return spi_legacy_resume(dev);
}
#else
#else
#define spi_suspend	NULL
#define spi_pm_suspend	NULL
#define spi_resume	NULL
#define spi_pm_resume	NULL
#define spi_pm_freeze	NULL
#define spi_pm_thaw	NULL
#define spi_pm_poweroff	NULL
#define spi_pm_restore	NULL
#endif
#endif


static const struct dev_pm_ops spi_pm = {
	.suspend = spi_pm_suspend,
	.resume = spi_pm_resume,
	.freeze = spi_pm_freeze,
	.thaw = spi_pm_thaw,
	.poweroff = spi_pm_poweroff,
	.restore = spi_pm_restore,
	SET_RUNTIME_PM_OPS(
		pm_generic_runtime_suspend,
		pm_generic_runtime_resume,
		pm_generic_runtime_idle
	)
};

struct bus_type spi_bus_type = {
struct bus_type spi_bus_type = {
	.name		= "spi",
	.name		= "spi",
	.dev_attrs	= spi_dev_attrs,
	.dev_attrs	= spi_dev_attrs,
	.match		= spi_match_device,
	.match		= spi_match_device,
	.uevent		= spi_uevent,
	.uevent		= spi_uevent,
	.suspend	= spi_suspend,
	.pm		= &spi_pm,
	.resume		= spi_resume,
};
};
EXPORT_SYMBOL_GPL(spi_bus_type);
EXPORT_SYMBOL_GPL(spi_bus_type);