diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2017-08-01 21:11:02 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-08-01 21:11:02 -0400 |
commit | a477b9cd37aa81a490dfa3265b7ff4f2c5a92463 (patch) | |
tree | 267e7a1f7da0e629dc7f8b5829f0afced68c41cf | |
parent | 16f73eb02d7e1765ccab3d2018e0bd98eb93d973 (diff) |
PCI: Add pci_reset_function_locked()
The implementation of PCI workarounds may require that the device is reset
from its probe function. This implies that the PCI device lock is already
held, and makes calling pci_reset_function() impossible (since it will
itself try to take that lock).
Add pci_reset_function_locked(), which is the equivalent of
pci_reset_function(), except that it requires the PCI device lock to be
already held by the caller.
Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
[bhelgaas: folded in fix for conflict with 52354b9d1f46 ("PCI: Remove
__pci_dev_reset() and pci_dev_reset()")]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org # 4.11: 52354b9d1f46: PCI: Remove __pci_dev_reset() and pci_dev_reset()
Cc: stable@vger.kernel.org # 4.11
-rw-r--r-- | drivers/pci/pci.c | 35 | ||||
-rw-r--r-- | include/linux/pci.h | 1 |
2 files changed, 36 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index af0cc3456dc1..b4b7eab29400 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -4260,6 +4260,41 @@ int pci_reset_function(struct pci_dev *dev) | |||
4260 | EXPORT_SYMBOL_GPL(pci_reset_function); | 4260 | EXPORT_SYMBOL_GPL(pci_reset_function); |
4261 | 4261 | ||
4262 | /** | 4262 | /** |
4263 | * pci_reset_function_locked - quiesce and reset a PCI device function | ||
4264 | * @dev: PCI device to reset | ||
4265 | * | ||
4266 | * Some devices allow an individual function to be reset without affecting | ||
4267 | * other functions in the same device. The PCI device must be responsive | ||
4268 | * to PCI config space in order to use this function. | ||
4269 | * | ||
4270 | * This function does not just reset the PCI portion of a device, but | ||
4271 | * clears all the state associated with the device. This function differs | ||
4272 | * from __pci_reset_function() in that it saves and restores device state | ||
4273 | * over the reset. It also differs from pci_reset_function() in that it | ||
4274 | * requires the PCI device lock to be held. | ||
4275 | * | ||
4276 | * Returns 0 if the device function was successfully reset or negative if the | ||
4277 | * device doesn't support resetting a single function. | ||
4278 | */ | ||
4279 | int pci_reset_function_locked(struct pci_dev *dev) | ||
4280 | { | ||
4281 | int rc; | ||
4282 | |||
4283 | rc = pci_probe_reset_function(dev); | ||
4284 | if (rc) | ||
4285 | return rc; | ||
4286 | |||
4287 | pci_dev_save_and_disable(dev); | ||
4288 | |||
4289 | rc = __pci_reset_function_locked(dev); | ||
4290 | |||
4291 | pci_dev_restore(dev); | ||
4292 | |||
4293 | return rc; | ||
4294 | } | ||
4295 | EXPORT_SYMBOL_GPL(pci_reset_function_locked); | ||
4296 | |||
4297 | /** | ||
4263 | * pci_try_reset_function - quiesce and reset a PCI device function | 4298 | * pci_try_reset_function - quiesce and reset a PCI device function |
4264 | * @dev: PCI device to reset | 4299 | * @dev: PCI device to reset |
4265 | * | 4300 | * |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 4869e66dd659..a75c13673852 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1067,6 +1067,7 @@ void pcie_flr(struct pci_dev *dev); | |||
1067 | int __pci_reset_function(struct pci_dev *dev); | 1067 | int __pci_reset_function(struct pci_dev *dev); |
1068 | int __pci_reset_function_locked(struct pci_dev *dev); | 1068 | int __pci_reset_function_locked(struct pci_dev *dev); |
1069 | int pci_reset_function(struct pci_dev *dev); | 1069 | int pci_reset_function(struct pci_dev *dev); |
1070 | int pci_reset_function_locked(struct pci_dev *dev); | ||
1070 | int pci_try_reset_function(struct pci_dev *dev); | 1071 | int pci_try_reset_function(struct pci_dev *dev); |
1071 | int pci_probe_reset_slot(struct pci_slot *slot); | 1072 | int pci_probe_reset_slot(struct pci_slot *slot); |
1072 | int pci_reset_slot(struct pci_slot *slot); | 1073 | int pci_reset_slot(struct pci_slot *slot); |