On Wed, Dec 22, 2010 at 02:28:23PM +0100, Rafael J. Wysocki wrote:
> On Wednesday, December 22, 2010, Mark Brown wrote:
> > 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: Mark Brown <[email protected]>
>
> It looks good to me.
I'll take that as an ack.
picked up for -next, thanks.
g.
>
> Thanks,
> Rafael
>
>
> > ---
> >
> > This depends on the patch 'PM: Prototype the pm_generic_ operations' I
> > posted recently to the PM and I2C lists, and has not exactly been
> > thoroughly tested yet.
> >
> > drivers/spi/spi.c | 92
> > ++++++++++++++++++++++++++++++++++++++++++++++++-----
> > 1 files changed, 84 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
> > index 709c836..85ad4b7 100644
> > --- a/drivers/spi/spi.c
> > +++ b/drivers/spi/spi.c
> > @@ -28,6 +28,7 @@
> > #include <linux/mod_devicetable.h>
> > #include <linux/spi/spi.h>
> > #include <linux/of_spi.h>
> > +#include <linux/pm_runtime.h>
> >
> > 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;
> > }
> >
> > -#ifdef CONFIG_PM
> > -
> > -static int spi_suspend(struct device *dev, pm_message_t message)
> > +#ifdef CONFIG_PM_SLEEP
> > +static int spi_legacy_suspend(struct device *dev, pm_message_t message)
> > {
> > int value = 0;
> > 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;
> > }
> >
> > -static int spi_resume(struct device *dev)
> > +static int spi_legacy_resume(struct device *dev)
> > {
> > int value = 0;
> > struct spi_driver *drv = to_spi_driver(dev->driver);
> > @@ -132,18 +132,94 @@ static int spi_resume(struct device *dev)
> > 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
> > -#define spi_suspend NULL
> > -#define spi_resume NULL
> > +#define spi_pm_suspend 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
> >
> > +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 = {
> > .name = "spi",
> > .dev_attrs = spi_dev_attrs,
> > .match = spi_match_device,
> > .uevent = spi_uevent,
> > - .suspend = spi_suspend,
> > - .resume = spi_resume,
> > + .pm = &spi_pm,
> > };
> > EXPORT_SYMBOL_GPL(spi_bus_type);
> >
> >
>
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________
spi-devel-general mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spi-devel-general