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

Reply via email to