diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e37fea6e178d..10ab64e8878e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3098,19 +3098,17 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask) | |||
3098 | } | 3098 | } |
3099 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); | 3099 | EXPORT_SYMBOL(pci_set_dma_seg_boundary); |
3100 | 3100 | ||
3101 | static int pcie_flr(struct pci_dev *dev, int probe) | 3101 | /** |
3102 | * pci_wait_for_pending_transaction - waits for pending transaction | ||
3103 | * @dev: the PCI device to operate on | ||
3104 | * | ||
3105 | * Return 0 if transaction is pending 1 otherwise. | ||
3106 | */ | ||
3107 | int pci_wait_for_pending_transaction(struct pci_dev *dev) | ||
3102 | { | 3108 | { |
3103 | int i; | 3109 | int i; |
3104 | u32 cap; | ||
3105 | u16 status; | 3110 | u16 status; |
3106 | 3111 | ||
3107 | pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); | ||
3108 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
3109 | return -ENOTTY; | ||
3110 | |||
3111 | if (probe) | ||
3112 | return 0; | ||
3113 | |||
3114 | /* Wait for Transaction Pending bit clean */ | 3112 | /* Wait for Transaction Pending bit clean */ |
3115 | for (i = 0; i < 4; i++) { | 3113 | for (i = 0; i < 4; i++) { |
3116 | if (i) | 3114 | if (i) |
@@ -3118,13 +3116,27 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
3118 | 3116 | ||
3119 | pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); | 3117 | pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); |
3120 | if (!(status & PCI_EXP_DEVSTA_TRPND)) | 3118 | if (!(status & PCI_EXP_DEVSTA_TRPND)) |
3121 | goto clear; | 3119 | return 1; |
3122 | } | 3120 | } |
3123 | 3121 | ||
3124 | dev_err(&dev->dev, "transaction is not cleared; " | 3122 | return 0; |
3125 | "proceeding with reset anyway\n"); | 3123 | } |
3124 | EXPORT_SYMBOL(pci_wait_for_pending_transaction); | ||
3125 | |||
3126 | static int pcie_flr(struct pci_dev *dev, int probe) | ||
3127 | { | ||
3128 | u32 cap; | ||
3129 | |||
3130 | pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); | ||
3131 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
3132 | return -ENOTTY; | ||
3133 | |||
3134 | if (probe) | ||
3135 | return 0; | ||
3136 | |||
3137 | if (!pci_wait_for_pending_transaction(dev)) | ||
3138 | dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n"); | ||
3126 | 3139 | ||
3127 | clear: | ||
3128 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); | 3140 | pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); |
3129 | 3141 | ||
3130 | msleep(100); | 3142 | msleep(100); |