diff options
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 158 |
1 files changed, 148 insertions, 10 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 315fea47e784..2b9ac9e594af 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -19,8 +19,8 @@ | |||
| 19 | #include <linux/pci-aspm.h> | 19 | #include <linux/pci-aspm.h> |
| 20 | #include <linux/pm_wakeup.h> | 20 | #include <linux/pm_wakeup.h> |
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | ||
| 23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
| 23 | #include <linux/pm_runtime.h> | ||
| 24 | #include <asm/setup.h> | 24 | #include <asm/setup.h> |
| 25 | #include "pci.h" | 25 | #include "pci.h" |
| 26 | 26 | ||
| @@ -29,6 +29,12 @@ const char *pci_power_names[] = { | |||
| 29 | }; | 29 | }; |
| 30 | EXPORT_SYMBOL_GPL(pci_power_names); | 30 | EXPORT_SYMBOL_GPL(pci_power_names); |
| 31 | 31 | ||
| 32 | int isa_dma_bridge_buggy; | ||
| 33 | EXPORT_SYMBOL(isa_dma_bridge_buggy); | ||
| 34 | |||
| 35 | int pci_pci_problems; | ||
| 36 | EXPORT_SYMBOL(pci_pci_problems); | ||
| 37 | |||
| 32 | unsigned int pci_pm_d3_delay; | 38 | unsigned int pci_pm_d3_delay; |
| 33 | 39 | ||
| 34 | static void pci_dev_d3_sleep(struct pci_dev *dev) | 40 | static void pci_dev_d3_sleep(struct pci_dev *dev) |
| @@ -380,10 +386,9 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
| 380 | { | 386 | { |
| 381 | const struct pci_bus *bus = dev->bus; | 387 | const struct pci_bus *bus = dev->bus; |
| 382 | int i; | 388 | int i; |
| 383 | struct resource *best = NULL; | 389 | struct resource *best = NULL, *r; |
| 384 | 390 | ||
| 385 | for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 391 | pci_bus_for_each_resource(bus, r, i) { |
| 386 | struct resource *r = bus->resource[i]; | ||
| 387 | if (!r) | 392 | if (!r) |
| 388 | continue; | 393 | continue; |
| 389 | if (res->start && !(res->start >= r->start && res->end <= r->end)) | 394 | if (res->start && !(res->start >= r->start && res->end <= r->end)) |
| @@ -457,6 +462,12 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
| 457 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; | 462 | pci_platform_pm->sleep_wake(dev, enable) : -ENODEV; |
| 458 | } | 463 | } |
| 459 | 464 | ||
| 465 | static inline int platform_pci_run_wake(struct pci_dev *dev, bool enable) | ||
| 466 | { | ||
| 467 | return pci_platform_pm ? | ||
| 468 | pci_platform_pm->run_wake(dev, enable) : -ENODEV; | ||
| 469 | } | ||
| 470 | |||
| 460 | /** | 471 | /** |
| 461 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of | 472 | * pci_raw_set_power_state - Use PCI PM registers to set the power state of |
| 462 | * given PCI device | 473 | * given PCI device |
| @@ -1190,6 +1201,66 @@ int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) | |||
| 1190 | } | 1201 | } |
| 1191 | 1202 | ||
| 1192 | /** | 1203 | /** |
| 1204 | * pci_check_pme_status - Check if given device has generated PME. | ||
| 1205 | * @dev: Device to check. | ||
| 1206 | * | ||
| 1207 | * Check the PME status of the device and if set, clear it and clear PME enable | ||
| 1208 | * (if set). Return 'true' if PME status and PME enable were both set or | ||
| 1209 | * 'false' otherwise. | ||
| 1210 | */ | ||
| 1211 | bool pci_check_pme_status(struct pci_dev *dev) | ||
| 1212 | { | ||
| 1213 | int pmcsr_pos; | ||
| 1214 | u16 pmcsr; | ||
| 1215 | bool ret = false; | ||
| 1216 | |||
| 1217 | if (!dev->pm_cap) | ||
| 1218 | return false; | ||
| 1219 | |||
| 1220 | pmcsr_pos = dev->pm_cap + PCI_PM_CTRL; | ||
| 1221 | pci_read_config_word(dev, pmcsr_pos, &pmcsr); | ||
| 1222 | if (!(pmcsr & PCI_PM_CTRL_PME_STATUS)) | ||
| 1223 | return false; | ||
| 1224 | |||
| 1225 | /* Clear PME status. */ | ||
| 1226 | pmcsr |= PCI_PM_CTRL_PME_STATUS; | ||
| 1227 | if (pmcsr & PCI_PM_CTRL_PME_ENABLE) { | ||
| 1228 | /* Disable PME to avoid interrupt flood. */ | ||
| 1229 | pmcsr &= ~PCI_PM_CTRL_PME_ENABLE; | ||
| 1230 | ret = true; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | pci_write_config_word(dev, pmcsr_pos, pmcsr); | ||
| 1234 | |||
| 1235 | return ret; | ||
| 1236 | } | ||
| 1237 | |||
| 1238 | /** | ||
| 1239 | * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set. | ||
| 1240 | * @dev: Device to handle. | ||
| 1241 | * @ign: Ignored. | ||
| 1242 | * | ||
| 1243 | * Check if @dev has generated PME and queue a resume request for it in that | ||
| 1244 | * case. | ||
| 1245 | */ | ||
| 1246 | static int pci_pme_wakeup(struct pci_dev *dev, void *ign) | ||
| 1247 | { | ||
| 1248 | if (pci_check_pme_status(dev)) | ||
| 1249 | pm_request_resume(&dev->dev); | ||
| 1250 | return 0; | ||
| 1251 | } | ||
| 1252 | |||
| 1253 | /** | ||
| 1254 | * pci_pme_wakeup_bus - Walk given bus and wake up devices on it, if necessary. | ||
| 1255 | * @bus: Top bus of the subtree to walk. | ||
| 1256 | */ | ||
| 1257 | void pci_pme_wakeup_bus(struct pci_bus *bus) | ||
| 1258 | { | ||
| 1259 | if (bus) | ||
| 1260 | pci_walk_bus(bus, pci_pme_wakeup, NULL); | ||
| 1261 | } | ||
| 1262 | |||
| 1263 | /** | ||
| 1193 | * pci_pme_capable - check the capability of PCI device to generate PME# | 1264 | * pci_pme_capable - check the capability of PCI device to generate PME# |
| 1194 | * @dev: PCI device to handle. | 1265 | * @dev: PCI device to handle. |
| 1195 | * @state: PCI state from which device will issue PME#. | 1266 | * @state: PCI state from which device will issue PME#. |
| @@ -1230,9 +1301,10 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
| 1230 | } | 1301 | } |
| 1231 | 1302 | ||
| 1232 | /** | 1303 | /** |
| 1233 | * pci_enable_wake - enable PCI device as wakeup event source | 1304 | * __pci_enable_wake - enable PCI device as wakeup event source |
| 1234 | * @dev: PCI device affected | 1305 | * @dev: PCI device affected |
| 1235 | * @state: PCI state from which device will issue wakeup events | 1306 | * @state: PCI state from which device will issue wakeup events |
| 1307 | * @runtime: True if the events are to be generated at run time | ||
| 1236 | * @enable: True to enable event generation; false to disable | 1308 | * @enable: True to enable event generation; false to disable |
| 1237 | * | 1309 | * |
| 1238 | * This enables the device as a wakeup event source, or disables it. | 1310 | * This enables the device as a wakeup event source, or disables it. |
| @@ -1248,11 +1320,12 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
| 1248 | * Error code depending on the platform is returned if both the platform and | 1320 | * Error code depending on the platform is returned if both the platform and |
| 1249 | * the native mechanism fail to enable the generation of wake-up events | 1321 | * the native mechanism fail to enable the generation of wake-up events |
| 1250 | */ | 1322 | */ |
| 1251 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | 1323 | int __pci_enable_wake(struct pci_dev *dev, pci_power_t state, |
| 1324 | bool runtime, bool enable) | ||
| 1252 | { | 1325 | { |
| 1253 | int ret = 0; | 1326 | int ret = 0; |
| 1254 | 1327 | ||
| 1255 | if (enable && !device_may_wakeup(&dev->dev)) | 1328 | if (enable && !runtime && !device_may_wakeup(&dev->dev)) |
| 1256 | return -EINVAL; | 1329 | return -EINVAL; |
| 1257 | 1330 | ||
| 1258 | /* Don't do the same thing twice in a row for one device. */ | 1331 | /* Don't do the same thing twice in a row for one device. */ |
| @@ -1272,19 +1345,24 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, bool enable) | |||
| 1272 | pci_pme_active(dev, true); | 1345 | pci_pme_active(dev, true); |
| 1273 | else | 1346 | else |
| 1274 | ret = 1; | 1347 | ret = 1; |
| 1275 | error = platform_pci_sleep_wake(dev, true); | 1348 | error = runtime ? platform_pci_run_wake(dev, true) : |
| 1349 | platform_pci_sleep_wake(dev, true); | ||
| 1276 | if (ret) | 1350 | if (ret) |
| 1277 | ret = error; | 1351 | ret = error; |
| 1278 | if (!ret) | 1352 | if (!ret) |
| 1279 | dev->wakeup_prepared = true; | 1353 | dev->wakeup_prepared = true; |
| 1280 | } else { | 1354 | } else { |
| 1281 | platform_pci_sleep_wake(dev, false); | 1355 | if (runtime) |
| 1356 | platform_pci_run_wake(dev, false); | ||
| 1357 | else | ||
| 1358 | platform_pci_sleep_wake(dev, false); | ||
| 1282 | pci_pme_active(dev, false); | 1359 | pci_pme_active(dev, false); |
| 1283 | dev->wakeup_prepared = false; | 1360 | dev->wakeup_prepared = false; |
| 1284 | } | 1361 | } |
| 1285 | 1362 | ||
| 1286 | return ret; | 1363 | return ret; |
| 1287 | } | 1364 | } |
| 1365 | EXPORT_SYMBOL(__pci_enable_wake); | ||
| 1288 | 1366 | ||
| 1289 | /** | 1367 | /** |
| 1290 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold | 1368 | * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold |
| @@ -1394,6 +1472,66 @@ int pci_back_from_sleep(struct pci_dev *dev) | |||
| 1394 | } | 1472 | } |
| 1395 | 1473 | ||
| 1396 | /** | 1474 | /** |
| 1475 | * pci_finish_runtime_suspend - Carry out PCI-specific part of runtime suspend. | ||
| 1476 | * @dev: PCI device being suspended. | ||
| 1477 | * | ||
| 1478 | * Prepare @dev to generate wake-up events at run time and put it into a low | ||
| 1479 | * power state. | ||
| 1480 | */ | ||
| 1481 | int pci_finish_runtime_suspend(struct pci_dev *dev) | ||
| 1482 | { | ||
| 1483 | pci_power_t target_state = pci_target_state(dev); | ||
| 1484 | int error; | ||
| 1485 | |||
| 1486 | if (target_state == PCI_POWER_ERROR) | ||
| 1487 | return -EIO; | ||
| 1488 | |||
| 1489 | __pci_enable_wake(dev, target_state, true, pci_dev_run_wake(dev)); | ||
| 1490 | |||
| 1491 | error = pci_set_power_state(dev, target_state); | ||
| 1492 | |||
| 1493 | if (error) | ||
| 1494 | __pci_enable_wake(dev, target_state, true, false); | ||
| 1495 | |||
| 1496 | return error; | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | /** | ||
| 1500 | * pci_dev_run_wake - Check if device can generate run-time wake-up events. | ||
| 1501 | * @dev: Device to check. | ||
| 1502 | * | ||
| 1503 | * Return true if the device itself is cabable of generating wake-up events | ||
| 1504 | * (through the platform or using the native PCIe PME) or if the device supports | ||
| 1505 | * PME and one of its upstream bridges can generate wake-up events. | ||
| 1506 | */ | ||
| 1507 | bool pci_dev_run_wake(struct pci_dev *dev) | ||
| 1508 | { | ||
| 1509 | struct pci_bus *bus = dev->bus; | ||
| 1510 | |||
| 1511 | if (device_run_wake(&dev->dev)) | ||
| 1512 | return true; | ||
| 1513 | |||
| 1514 | if (!dev->pme_support) | ||
| 1515 | return false; | ||
| 1516 | |||
| 1517 | while (bus->parent) { | ||
| 1518 | struct pci_dev *bridge = bus->self; | ||
| 1519 | |||
| 1520 | if (device_run_wake(&bridge->dev)) | ||
| 1521 | return true; | ||
| 1522 | |||
| 1523 | bus = bus->parent; | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | /* We have reached the root bus. */ | ||
| 1527 | if (bus->bridge) | ||
| 1528 | return device_run_wake(bus->bridge); | ||
| 1529 | |||
| 1530 | return false; | ||
| 1531 | } | ||
| 1532 | EXPORT_SYMBOL_GPL(pci_dev_run_wake); | ||
| 1533 | |||
| 1534 | /** | ||
| 1397 | * pci_pm_init - Initialize PM functions of given PCI device | 1535 | * pci_pm_init - Initialize PM functions of given PCI device |
| 1398 | * @dev: PCI device to handle. | 1536 | * @dev: PCI device to handle. |
| 1399 | */ | 1537 | */ |
| @@ -1402,6 +1540,7 @@ void pci_pm_init(struct pci_dev *dev) | |||
| 1402 | int pm; | 1540 | int pm; |
| 1403 | u16 pmc; | 1541 | u16 pmc; |
| 1404 | 1542 | ||
| 1543 | device_enable_async_suspend(&dev->dev); | ||
| 1405 | dev->wakeup_prepared = false; | 1544 | dev->wakeup_prepared = false; |
| 1406 | dev->pm_cap = 0; | 1545 | dev->pm_cap = 0; |
| 1407 | 1546 | ||
| @@ -2871,7 +3010,6 @@ EXPORT_SYMBOL(pci_save_state); | |||
| 2871 | EXPORT_SYMBOL(pci_restore_state); | 3010 | EXPORT_SYMBOL(pci_restore_state); |
| 2872 | EXPORT_SYMBOL(pci_pme_capable); | 3011 | EXPORT_SYMBOL(pci_pme_capable); |
| 2873 | EXPORT_SYMBOL(pci_pme_active); | 3012 | EXPORT_SYMBOL(pci_pme_active); |
| 2874 | EXPORT_SYMBOL(pci_enable_wake); | ||
| 2875 | EXPORT_SYMBOL(pci_wake_from_d3); | 3013 | EXPORT_SYMBOL(pci_wake_from_d3); |
| 2876 | EXPORT_SYMBOL(pci_target_state); | 3014 | EXPORT_SYMBOL(pci_target_state); |
| 2877 | EXPORT_SYMBOL(pci_prepare_to_sleep); | 3015 | EXPORT_SYMBOL(pci_prepare_to_sleep); |
