diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8e8ecc1da93d..f8074525267c 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -376,7 +376,32 @@ pci_restore_bars(struct pci_dev *dev) | |||
376 | pci_update_resource(dev, &dev->resource[i], i); | 376 | pci_update_resource(dev, &dev->resource[i], i); |
377 | } | 377 | } |
378 | 378 | ||
379 | int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t); | 379 | static struct pci_platform_pm_ops *pci_platform_pm; |
380 | |||
381 | int pci_set_platform_pm(struct pci_platform_pm_ops *ops) | ||
382 | { | ||
383 | if (!ops->is_manageable || !ops->set_state || !ops->choose_state) | ||
384 | return -EINVAL; | ||
385 | pci_platform_pm = ops; | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static inline bool platform_pci_power_manageable(struct pci_dev *dev) | ||
390 | { | ||
391 | return pci_platform_pm ? pci_platform_pm->is_manageable(dev) : false; | ||
392 | } | ||
393 | |||
394 | static inline int platform_pci_set_power_state(struct pci_dev *dev, | ||
395 | pci_power_t t) | ||
396 | { | ||
397 | return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS; | ||
398 | } | ||
399 | |||
400 | static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) | ||
401 | { | ||
402 | return pci_platform_pm ? | ||
403 | pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; | ||
404 | } | ||
380 | 405 | ||
381 | /** | 406 | /** |
382 | * pci_set_power_state - Set the power state of a PCI device | 407 | * pci_set_power_state - Set the power state of a PCI device |
@@ -479,8 +504,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
479 | * Give firmware a chance to be called, such as ACPI _PRx, _PSx | 504 | * Give firmware a chance to be called, such as ACPI _PRx, _PSx |
480 | * Firmware method after native method ? | 505 | * Firmware method after native method ? |
481 | */ | 506 | */ |
482 | if (platform_pci_set_power_state) | 507 | platform_pci_set_power_state(dev, state); |
483 | platform_pci_set_power_state(dev, state); | ||
484 | 508 | ||
485 | dev->current_state = state; | 509 | dev->current_state = state; |
486 | 510 | ||
@@ -505,8 +529,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
505 | return 0; | 529 | return 0; |
506 | } | 530 | } |
507 | 531 | ||
508 | pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev); | ||
509 | |||
510 | /** | 532 | /** |
511 | * pci_choose_state - Choose the power state of a PCI device | 533 | * pci_choose_state - Choose the power state of a PCI device |
512 | * @dev: PCI device to be suspended | 534 | * @dev: PCI device to be suspended |
@@ -524,11 +546,9 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) | |||
524 | if (!pci_find_capability(dev, PCI_CAP_ID_PM)) | 546 | if (!pci_find_capability(dev, PCI_CAP_ID_PM)) |
525 | return PCI_D0; | 547 | return PCI_D0; |
526 | 548 | ||
527 | if (platform_pci_choose_state) { | 549 | ret = platform_pci_choose_state(dev); |
528 | ret = platform_pci_choose_state(dev); | 550 | if (ret != PCI_POWER_ERROR) |
529 | if (ret != PCI_POWER_ERROR) | 551 | return ret; |
530 | return ret; | ||
531 | } | ||
532 | 552 | ||
533 | switch (state.event) { | 553 | switch (state.event) { |
534 | case PM_EVENT_ON: | 554 | case PM_EVENT_ON: |