aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 18:23:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 18:23:53 -0500
commitad56cbf0fa6c09350c738ec59a3361f2e4ab4bc7 (patch)
tree35c166dcc1c29b04cea3cdf8ff9a65fcfe9bed91
parentab0724ffee24409a7f81afb539b2ac29090bff3e (diff)
parentf4e8db31a83ad019e9ae06edb9c2f89de66bc7b7 (diff)
Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging
* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging: i2c: Encourage move to dev_pm_ops by warning on use of legacy methods i2c: Factor out runtime suspend checks from PM operations i2c: Unregister dummy devices last on adapter removal
-rw-r--r--drivers/i2c/i2c-core.c90
1 files changed, 41 insertions, 49 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index c7db6980e3a3..f0bd5bcdf563 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -196,88 +196,60 @@ static int i2c_device_pm_suspend(struct device *dev)
196{ 196{
197 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 197 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
198 198
199 if (pm) { 199 if (pm)
200 if (pm_runtime_suspended(dev)) 200 return pm_generic_suspend(dev);
201 return 0; 201 else
202 else 202 return i2c_legacy_suspend(dev, PMSG_SUSPEND);
203 return pm->suspend ? pm->suspend(dev) : 0;
204 }
205
206 return i2c_legacy_suspend(dev, PMSG_SUSPEND);
207} 203}
208 204
209static int i2c_device_pm_resume(struct device *dev) 205static int i2c_device_pm_resume(struct device *dev)
210{ 206{
211 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 207 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
212 int ret;
213 208
214 if (pm) 209 if (pm)
215 ret = pm->resume ? pm->resume(dev) : 0; 210 return pm_generic_resume(dev);
216 else 211 else
217 ret = i2c_legacy_resume(dev); 212 return i2c_legacy_resume(dev);
218
219 return ret;
220} 213}
221 214
222static int i2c_device_pm_freeze(struct device *dev) 215static int i2c_device_pm_freeze(struct device *dev)
223{ 216{
224 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 217 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
225 218
226 if (pm) { 219 if (pm)
227 if (pm_runtime_suspended(dev)) 220 return pm_generic_freeze(dev);
228 return 0; 221 else
229 else 222 return i2c_legacy_suspend(dev, PMSG_FREEZE);
230 return pm->freeze ? pm->freeze(dev) : 0;
231 }
232
233 return i2c_legacy_suspend(dev, PMSG_FREEZE);
234} 223}
235 224
236static int i2c_device_pm_thaw(struct device *dev) 225static int i2c_device_pm_thaw(struct device *dev)
237{ 226{
238 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 227 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
239 228
240 if (pm) { 229 if (pm)
241 if (pm_runtime_suspended(dev)) 230 return pm_generic_thaw(dev);
242 return 0; 231 else
243 else 232 return i2c_legacy_resume(dev);
244 return pm->thaw ? pm->thaw(dev) : 0;
245 }
246
247 return i2c_legacy_resume(dev);
248} 233}
249 234
250static int i2c_device_pm_poweroff(struct device *dev) 235static int i2c_device_pm_poweroff(struct device *dev)
251{ 236{
252 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 237 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
253 238
254 if (pm) { 239 if (pm)
255 if (pm_runtime_suspended(dev)) 240 return pm_generic_poweroff(dev);
256 return 0; 241 else
257 else 242 return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
258 return pm->poweroff ? pm->poweroff(dev) : 0;
259 }
260
261 return i2c_legacy_suspend(dev, PMSG_HIBERNATE);
262} 243}
263 244
264static int i2c_device_pm_restore(struct device *dev) 245static int i2c_device_pm_restore(struct device *dev)
265{ 246{
266 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 247 const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
267 int ret;
268 248
269 if (pm) 249 if (pm)
270 ret = pm->restore ? pm->restore(dev) : 0; 250 return pm_generic_restore(dev);
271 else 251 else
272 ret = i2c_legacy_resume(dev); 252 return i2c_legacy_resume(dev);
273
274 if (!ret) {
275 pm_runtime_disable(dev);
276 pm_runtime_set_active(dev);
277 pm_runtime_enable(dev);
278 }
279
280 return ret;
281} 253}
282#else /* !CONFIG_PM_SLEEP */ 254#else /* !CONFIG_PM_SLEEP */
283#define i2c_device_pm_suspend NULL 255#define i2c_device_pm_suspend NULL
@@ -1021,6 +993,14 @@ static int i2c_do_del_adapter(struct i2c_driver *driver,
1021static int __unregister_client(struct device *dev, void *dummy) 993static int __unregister_client(struct device *dev, void *dummy)
1022{ 994{
1023 struct i2c_client *client = i2c_verify_client(dev); 995 struct i2c_client *client = i2c_verify_client(dev);
996 if (client && strcmp(client->name, "dummy"))
997 i2c_unregister_device(client);
998 return 0;
999}
1000
1001static int __unregister_dummy(struct device *dev, void *dummy)
1002{
1003 struct i2c_client *client = i2c_verify_client(dev);
1024 if (client) 1004 if (client)
1025 i2c_unregister_device(client); 1005 i2c_unregister_device(client);
1026 return 0; 1006 return 0;
@@ -1075,8 +1055,12 @@ int i2c_del_adapter(struct i2c_adapter *adap)
1075 mutex_unlock(&adap->userspace_clients_lock); 1055 mutex_unlock(&adap->userspace_clients_lock);
1076 1056
1077 /* Detach any active clients. This can't fail, thus we do not 1057 /* Detach any active clients. This can't fail, thus we do not
1078 checking the returned value. */ 1058 * check the returned value. This is a two-pass process, because
1059 * we can't remove the dummy devices during the first pass: they
1060 * could have been instantiated by real devices wishing to clean
1061 * them up properly, so we give them a chance to do that first. */
1079 res = device_for_each_child(&adap->dev, NULL, __unregister_client); 1062 res = device_for_each_child(&adap->dev, NULL, __unregister_client);
1063 res = device_for_each_child(&adap->dev, NULL, __unregister_dummy);
1080 1064
1081#ifdef CONFIG_I2C_COMPAT 1065#ifdef CONFIG_I2C_COMPAT
1082 class_compat_remove_link(i2c_adapter_compat_class, &adap->dev, 1066 class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,
@@ -1140,6 +1124,14 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
1140 if (res) 1124 if (res)
1141 return res; 1125 return res;
1142 1126
1127 /* Drivers should switch to dev_pm_ops instead. */
1128 if (driver->suspend)
1129 pr_warn("i2c-core: driver [%s] using legacy suspend method\n",
1130 driver->driver.name);
1131 if (driver->resume)
1132 pr_warn("i2c-core: driver [%s] using legacy resume method\n",
1133 driver->driver.name);
1134
1143 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); 1135 pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
1144 1136
1145 INIT_LIST_HEAD(&driver->clients); 1137 INIT_LIST_HEAD(&driver->clients);