diff options
| -rw-r--r-- | drivers/pcmcia/yenta_socket.c | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 6fa1ed8f2b2f..abe0e44c6e9e 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
| @@ -1225,60 +1225,71 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i | |||
| 1225 | } | 1225 | } |
| 1226 | 1226 | ||
| 1227 | #ifdef CONFIG_PM | 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 | int ret; | 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) |
| 1236 | if (socket->type && socket->type->save_state) | 1237 | return ret; |
| 1237 | socket->type->save_state(socket); | ||
| 1238 | 1238 | ||
| 1239 | /* FIXME: pci_save_state needs to have a better interface */ | 1239 | if (socket->type && socket->type->save_state) |
| 1240 | pci_save_state(dev); | 1240 | socket->type->save_state(socket); |
| 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); | ||
| 1244 | 1241 | ||
| 1245 | /* | 1242 | pci_save_state(pdev); |
| 1246 | * Some laptops (IBM T22) do not like us putting the Cardbus | 1243 | pci_read_config_dword(pdev, 16*4, &socket->saved_state[0]); |
| 1247 | * bridge into D3. At a guess, some other laptop will | 1244 | pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]); |
| 1248 | * probably require this, so leave it commented out for now. | 1245 | pci_disable_device(pdev); |
| 1249 | */ | 1246 | |
| 1250 | /* pci_set_power_state(dev, 3); */ | 1247 | /* |
| 1251 | } | 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 | return ret; | 1254 | return ret; |
| 1254 | } | 1255 | } |
| 1255 | 1256 | ||
| 1256 | 1257 | static int yenta_dev_resume_noirq(struct device *dev) | |
| 1257 | static int yenta_dev_resume (struct pci_dev *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) { | 1263 | if (!socket) |
| 1262 | int rc; | 1264 | return 0; |
| 1263 | 1265 | ||
| 1264 | pci_set_power_state(dev, 0); | 1266 | pci_write_config_dword(pdev, 16*4, socket->saved_state[0]); |
| 1265 | /* FIXME: pci_restore_state needs to have a better interface */ | 1267 | pci_write_config_dword(pdev, 17*4, socket->saved_state[1]); |
| 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]); | ||
| 1269 | 1268 | ||
| 1270 | rc = pci_enable_device(dev); | 1269 | ret = pci_enable_device(pdev); |
| 1271 | if (rc) | 1270 | if (ret) |
| 1272 | return rc; | 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) | 1275 | if (socket->type && socket->type->restore_state) |
| 1277 | socket->type->restore_state(socket); | 1276 | socket->type->restore_state(socket); |
| 1278 | } | ||
| 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 (¥ta_pm_ops) | ||
| 1291 | #else | ||
| 1292 | #define YENTA_PM_OPS NULL | ||
| 1282 | #endif | 1293 | #endif |
| 1283 | 1294 | ||
| 1284 | #define CB_ID(vend,dev,type) \ | 1295 | #define CB_ID(vend,dev,type) \ |
| @@ -1376,10 +1387,7 @@ static struct pci_driver yenta_cardbus_driver = { | |||
| 1376 | .id_table = yenta_table, | 1387 | .id_table = yenta_table, |
| 1377 | .probe = yenta_probe, | 1388 | .probe = yenta_probe, |
| 1378 | .remove = __devexit_p(yenta_close), | 1389 | .remove = __devexit_p(yenta_close), |
| 1379 | #ifdef CONFIG_PM | 1390 | .driver.pm = YENTA_PM_OPS, |
| 1380 | .suspend = yenta_dev_suspend, | ||
| 1381 | .resume = yenta_dev_resume, | ||
| 1382 | #endif | ||
| 1383 | }; | 1391 | }; |
| 1384 | 1392 | ||
| 1385 | 1393 | ||
