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

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
...@@ -28,6 +28,7 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment