diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 73 |
1 files changed, 58 insertions, 15 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 16fd0d4c3166..1a91bf9687af 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -557,7 +557,8 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
557 | } else { | 557 | } else { |
558 | error = -ENODEV; | 558 | error = -ENODEV; |
559 | /* Fall back to PCI_D0 if native PM is not supported */ | 559 | /* Fall back to PCI_D0 if native PM is not supported */ |
560 | pci_update_current_state(dev, PCI_D0); | 560 | if (!dev->pm_cap) |
561 | dev->current_state = PCI_D0; | ||
561 | } | 562 | } |
562 | 563 | ||
563 | return error; | 564 | return error; |
@@ -681,11 +682,34 @@ EXPORT_SYMBOL(pci_choose_state); | |||
681 | 682 | ||
682 | #define PCI_EXP_SAVE_REGS 7 | 683 | #define PCI_EXP_SAVE_REGS 7 |
683 | 684 | ||
685 | #define pcie_cap_has_devctl(type, flags) 1 | ||
686 | #define pcie_cap_has_lnkctl(type, flags) \ | ||
687 | ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ | ||
688 | (type == PCI_EXP_TYPE_ROOT_PORT || \ | ||
689 | type == PCI_EXP_TYPE_ENDPOINT || \ | ||
690 | type == PCI_EXP_TYPE_LEG_END)) | ||
691 | #define pcie_cap_has_sltctl(type, flags) \ | ||
692 | ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ | ||
693 | ((type == PCI_EXP_TYPE_ROOT_PORT) || \ | ||
694 | (type == PCI_EXP_TYPE_DOWNSTREAM && \ | ||
695 | (flags & PCI_EXP_FLAGS_SLOT)))) | ||
696 | #define pcie_cap_has_rtctl(type, flags) \ | ||
697 | ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ | ||
698 | (type == PCI_EXP_TYPE_ROOT_PORT || \ | ||
699 | type == PCI_EXP_TYPE_RC_EC)) | ||
700 | #define pcie_cap_has_devctl2(type, flags) \ | ||
701 | ((flags & PCI_EXP_FLAGS_VERS) > 1) | ||
702 | #define pcie_cap_has_lnkctl2(type, flags) \ | ||
703 | ((flags & PCI_EXP_FLAGS_VERS) > 1) | ||
704 | #define pcie_cap_has_sltctl2(type, flags) \ | ||
705 | ((flags & PCI_EXP_FLAGS_VERS) > 1) | ||
706 | |||
684 | static int pci_save_pcie_state(struct pci_dev *dev) | 707 | static int pci_save_pcie_state(struct pci_dev *dev) |
685 | { | 708 | { |
686 | int pos, i = 0; | 709 | int pos, i = 0; |
687 | struct pci_cap_saved_state *save_state; | 710 | struct pci_cap_saved_state *save_state; |
688 | u16 *cap; | 711 | u16 *cap; |
712 | u16 flags; | ||
689 | 713 | ||
690 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 714 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
691 | if (pos <= 0) | 715 | if (pos <= 0) |
@@ -698,13 +722,22 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
698 | } | 722 | } |
699 | cap = (u16 *)&save_state->data[0]; | 723 | cap = (u16 *)&save_state->data[0]; |
700 | 724 | ||
701 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]); | 725 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); |
702 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); | 726 | |
703 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); | 727 | if (pcie_cap_has_devctl(dev->pcie_type, flags)) |
704 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); | 728 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]); |
705 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); | 729 | if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) |
706 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); | 730 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); |
707 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); | 731 | if (pcie_cap_has_sltctl(dev->pcie_type, flags)) |
732 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); | ||
733 | if (pcie_cap_has_rtctl(dev->pcie_type, flags)) | ||
734 | pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); | ||
735 | if (pcie_cap_has_devctl2(dev->pcie_type, flags)) | ||
736 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); | ||
737 | if (pcie_cap_has_lnkctl2(dev->pcie_type, flags)) | ||
738 | pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); | ||
739 | if (pcie_cap_has_sltctl2(dev->pcie_type, flags)) | ||
740 | pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); | ||
708 | 741 | ||
709 | return 0; | 742 | return 0; |
710 | } | 743 | } |
@@ -714,6 +747,7 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
714 | int i = 0, pos; | 747 | int i = 0, pos; |
715 | struct pci_cap_saved_state *save_state; | 748 | struct pci_cap_saved_state *save_state; |
716 | u16 *cap; | 749 | u16 *cap; |
750 | u16 flags; | ||
717 | 751 | ||
718 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 752 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
719 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 753 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
@@ -721,13 +755,22 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
721 | return; | 755 | return; |
722 | cap = (u16 *)&save_state->data[0]; | 756 | cap = (u16 *)&save_state->data[0]; |
723 | 757 | ||
724 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]); | 758 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); |
725 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); | 759 | |
726 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); | 760 | if (pcie_cap_has_devctl(dev->pcie_type, flags)) |
727 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); | 761 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]); |
728 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); | 762 | if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) |
729 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); | 763 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); |
730 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); | 764 | if (pcie_cap_has_sltctl(dev->pcie_type, flags)) |
765 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); | ||
766 | if (pcie_cap_has_rtctl(dev->pcie_type, flags)) | ||
767 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); | ||
768 | if (pcie_cap_has_devctl2(dev->pcie_type, flags)) | ||
769 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); | ||
770 | if (pcie_cap_has_lnkctl2(dev->pcie_type, flags)) | ||
771 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); | ||
772 | if (pcie_cap_has_sltctl2(dev->pcie_type, flags)) | ||
773 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); | ||
731 | } | 774 | } |
732 | 775 | ||
733 | 776 | ||