aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-25 09:32:27 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2010-12-25 09:32:27 -0500
commit3ae22e8c8ac39daf88ae32f047fb23825be7c646 (patch)
tree20e7ed1005b39e65d99ac351776e74a9c925a6aa
parent62bcb91573425975d6ad2389d7ab1d8feca88ab4 (diff)
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: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--drivers/spi/spi.c92
1 files changed, 84 insertions, 8 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index b02d0cbce890..34bb17f03019 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -28,6 +28,7 @@
28#include <linux/mod_devicetable.h> 28#include <linux/mod_devicetable.h>
29#include <linux/spi/spi.h> 29#include <linux/spi/spi.h>
30#include <linux/of_spi.h> 30#include <linux/of_spi.h>
31#include <linux/pm_runtime.h>
31 32
32static void spidev_release(struct device *dev) 33static void spidev_release(struct device *dev)
33{ 34{
@@ -100,9 +101,8 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
100 return 0; 101 return 0;
101} 102}
102 103
103#ifdef CONFIG_PM 104#ifdef CONFIG_PM_SLEEP
104 105static int spi_legacy_suspend(struct device *dev, pm_message_t message)
105static int spi_suspend(struct device *dev, pm_message_t message)
106{ 106{
107 int value = 0; 107 int value = 0;
108 struct spi_driver *drv = to_spi_driver(dev->driver); 108 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 return value; 117 return value;
118} 118}
119 119
120static int spi_resume(struct device *dev) 120static int spi_legacy_resume(struct device *dev)
121{ 121{
122 int value = 0; 122 int value = 0;
123 struct spi_driver *drv = to_spi_driver(dev->driver); 123 struct spi_driver *drv = to_spi_driver(dev->driver);
@@ -132,18 +132,94 @@ static int spi_resume(struct device *dev)
132 return value; 132 return value;
133} 133}
134 134
135static int spi_pm_suspend(struct device *dev)
136{
137 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
138
139 if (pm)
140 return pm_generic_suspend(dev);
141 else
142 return spi_legacy_suspend(dev, PMSG_SUSPEND);
143}
144
145static int spi_pm_resume(struct device *dev)
146{
147 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
148
149 if (pm)
150 return pm_generic_resume(dev);
151 else
152 return spi_legacy_resume(dev);
153}
154
155static int spi_pm_freeze(struct device *dev)
156{
157 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
158
159 if (pm)
160 return pm_generic_freeze(dev);
161 else
162 return spi_legacy_suspend(dev, PMSG_FREEZE);
163}
164
165static int spi_pm_thaw(struct device *dev)
166{
167 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
168
169 if (pm)
170 return pm_generic_thaw(dev);
171 else
172 return spi_legacy_resume(dev);
173}
174
175static int spi_pm_poweroff(struct device *dev)
176{
177 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
178
179 if (pm)
180 return pm_generic_poweroff(dev);
181 else
182 return spi_legacy_suspend(dev, PMSG_HIBERNATE);
183}
184
185static int spi_pm_restore(struct device *dev)
186{
187 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
188
189 if (pm)
190 return pm_generic_restore(dev);
191 else
192 return spi_legacy_resume(dev);
193}
135#else 194#else
136#define spi_suspend NULL 195#define spi_pm_suspend NULL
137#define spi_resume NULL 196#define spi_pm_resume NULL
197#define spi_pm_freeze NULL
198#define spi_pm_thaw NULL
199#define spi_pm_poweroff NULL
200#define spi_pm_restore NULL
138#endif 201#endif
139 202
203static const struct dev_pm_ops spi_pm = {
204 .suspend = spi_pm_suspend,
205 .resume = spi_pm_resume,
206 .freeze = spi_pm_freeze,
207 .thaw = spi_pm_thaw,
208 .poweroff = spi_pm_poweroff,
209 .restore = spi_pm_restore,
210 SET_RUNTIME_PM_OPS(
211 pm_generic_runtime_suspend,
212 pm_generic_runtime_resume,
213 pm_generic_runtime_idle
214 )
215};
216
140struct bus_type spi_bus_type = { 217struct bus_type spi_bus_type = {
141 .name = "spi", 218 .name = "spi",
142 .dev_attrs = spi_dev_attrs, 219 .dev_attrs = spi_dev_attrs,
143 .match = spi_match_device, 220 .match = spi_match_device,
144 .uevent = spi_uevent, 221 .uevent = spi_uevent,
145 .suspend = spi_suspend, 222 .pm = &spi_pm,
146 .resume = spi_resume,
147}; 223};
148EXPORT_SYMBOL_GPL(spi_bus_type); 224EXPORT_SYMBOL_GPL(spi_bus_type);
149 225