PM / yenta: Fix cardbus suspend/resume regression

Since 2.6.29 the PCI PM core have been restoring the standard
configuration registers of PCI devices in the early phase of
resume. In particular, PCI devices without drivers have been handled
this way since commit 355a72d75b3b4f4877db4c9070c798238028ecb5
(PCI: Rework default handling of suspend and resume). Unfortunately,
this leads to post-resume problems with CardBus devices which cannot
be accessed in the early phase of resume, because the sockets they
are on have not been woken up yet at that point.

To solve this problem, move the yenta socket resume to the early
phase of resume and, analogously, move the suspend of it to the late
phase of suspend. Additionally, remove some unnecessary PCI code
from the yenta socket's resume routine.

Fixes http://bugzilla.kernel.org/show_bug.cgi?id=13092, which is a
post-2.6.28 regression.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reported-by: Florian <fs-kernelbugzilla@spline.de>
Cc: stable@kernel.org

+48 -40
+48 -40
drivers/pcmcia/yenta_socket.c
··· 1225 1225 } 1226 1226 1227 1227 #ifdef CONFIG_PM 1228 - static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state) 1228 + static int yenta_dev_suspend_noirq(struct device *dev) 1229 1229 { 1230 - struct yenta_socket *socket = pci_get_drvdata(dev); 1230 + struct pci_dev *pdev = to_pci_dev(dev); 1231 + struct yenta_socket *socket = pci_get_drvdata(pdev); 1231 1232 int ret; 1232 1233 1233 - ret = pcmcia_socket_dev_suspend(&dev->dev); 1234 + ret = pcmcia_socket_dev_suspend(dev); 1234 1235 1235 - if (socket) { 1236 - if (socket->type && socket->type->save_state) 1237 - socket->type->save_state(socket); 1236 + if (!socket) 1237 + return ret; 1238 1238 1239 - /* FIXME: pci_save_state needs to have a better interface */ 1240 - pci_save_state(dev); 1241 - pci_read_config_dword(dev, 16*4, &socket->saved_state[0]); 1242 - pci_read_config_dword(dev, 17*4, &socket->saved_state[1]); 1243 - pci_disable_device(dev); 1239 + if (socket->type && socket->type->save_state) 1240 + socket->type->save_state(socket); 1244 1241 1245 - /* 1246 - * Some laptops (IBM T22) do not like us putting the Cardbus 1247 - * bridge into D3. At a guess, some other laptop will 1248 - * probably require this, so leave it commented out for now. 1249 - */ 1250 - /* pci_set_power_state(dev, 3); */ 1251 - } 1242 + pci_save_state(pdev); 1243 + pci_read_config_dword(pdev, 16*4, &socket->saved_state[0]); 1244 + pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); 1245 + pci_disable_device(pdev); 1246 + 1247 + /* 1248 + * Some laptops (IBM T22) do not like us putting the Cardbus 1249 + * bridge into D3. At a guess, some other laptop will 1250 + * probably require this, so leave it commented out for now. 1251 + */ 1252 + /* pci_set_power_state(dev, 3); */ 1252 1253 1253 1254 return ret; 1254 1255 } 1255 1256 1256 - 1257 - static int yenta_dev_resume (struct pci_dev *dev) 1257 + static int yenta_dev_resume_noirq(struct device *dev) 1258 1258 { 1259 - struct yenta_socket *socket = pci_get_drvdata(dev); 1259 + struct pci_dev *pdev = to_pci_dev(dev); 1260 + struct yenta_socket *socket = pci_get_drvdata(pdev); 1261 + int ret; 1260 1262 1261 - if (socket) { 1262 - int rc; 1263 + if (!socket) 1264 + return 0; 1263 1265 1264 - pci_set_power_state(dev, 0); 1265 - /* FIXME: pci_restore_state needs to have a better interface */ 1266 - pci_restore_state(dev); 1267 - pci_write_config_dword(dev, 16*4, socket->saved_state[0]); 1268 - pci_write_config_dword(dev, 17*4, socket->saved_state[1]); 1266 + pci_write_config_dword(pdev, 16*4, socket->saved_state[0]); 1267 + pci_write_config_dword(pdev, 17*4, socket->saved_state[1]); 1269 1268 1270 - rc = pci_enable_device(dev); 1271 - if (rc) 1272 - return rc; 1269 + ret = pci_enable_device(pdev); 1270 + if (ret) 1271 + return ret; 1273 1272 1274 - pci_set_master(dev); 1273 + pci_set_master(pdev); 1275 1274 1276 - if (socket->type && socket->type->restore_state) 1277 - socket->type->restore_state(socket); 1278 - } 1275 + if (socket->type && socket->type->restore_state) 1276 + socket->type->restore_state(socket); 1279 1277 1280 - return pcmcia_socket_dev_resume(&dev->dev); 1278 + return pcmcia_socket_dev_resume(dev); 1281 1279 } 1280 + 1281 + static struct dev_pm_ops yenta_pm_ops = { 1282 + .suspend_noirq = yenta_dev_suspend_noirq, 1283 + .resume_noirq = yenta_dev_resume_noirq, 1284 + .freeze_noirq = yenta_dev_suspend_noirq, 1285 + .thaw_noirq = yenta_dev_resume_noirq, 1286 + .poweroff_noirq = yenta_dev_suspend_noirq, 1287 + .restore_noirq = yenta_dev_resume_noirq, 1288 + }; 1289 + 1290 + #define YENTA_PM_OPS (&yenta_pm_ops) 1291 + #else 1292 + #define YENTA_PM_OPS NULL 1282 1293 #endif 1283 1294 1284 1295 #define CB_ID(vend,dev,type) \ ··· 1387 1376 .id_table = yenta_table, 1388 1377 .probe = yenta_probe, 1389 1378 .remove = __devexit_p(yenta_close), 1390 - #ifdef CONFIG_PM 1391 - .suspend = yenta_dev_suspend, 1392 - .resume = yenta_dev_resume, 1393 - #endif 1379 + .driver.pm = YENTA_PM_OPS, 1394 1380 }; 1395 1381 1396 1382