diff options
Diffstat (limited to 'drivers/pcmcia/yenta_socket.c')
-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 | ||