| From brking@linux.vnet.ibm.com Fri Apr 6 14:39:42 2007 |
| From: Brian King <brking@linux.vnet.ibm.com> |
| Date: Fri, 06 Apr 2007 16:39:36 -0500 |
| Subject: [PATCH 1/1] pci: New PCI-E reset API |
| To: greg@kroah.com |
| Cc: linux-pci@atrey.karlin.mff.cuni.cz, thlin@linux.vnet.ibm.com, linas@austin.ibm.com, brking@linux.vnet.ibm.com |
| Message-ID: <11758955741740-patch-mail.ibm.com> |
| |
| |
| |
| Adds a new API which can be used to issue various types |
| of PCI-E reset, including PCI-E warm reset and PCI-E hot reset. |
| This is needed for an ipr PCI-E adapter which does not properly |
| implement BIST. Running BIST on this adapter results in PCI-E |
| errors. The only reliable reset mechanism that exists on this |
| hardware is PCI Fundamental reset (warm reset). Since driving |
| this type of reset is architecture unique, this provides the |
| necessary hooks for architectures to add this support. |
| |
| Signed-off-by: Brian King <brking@linux.vnet.ibm.com> |
| Acked-by: Linas Vepstas <linas@austin.ibm.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/pci/pci.c | 29 +++++++++++++++++++++++++++++ |
| include/linux/pci.h | 14 ++++++++++++++ |
| 2 files changed, 43 insertions(+) |
| |
| --- a/drivers/pci/pci.c |
| +++ b/drivers/pci/pci.c |
| @@ -892,6 +892,34 @@ pci_disable_device(struct pci_dev *dev) |
| } |
| |
| /** |
| + * pcibios_set_pcie_reset_state - set reset state for device dev |
| + * @dev: the PCI-E device reset |
| + * @state: Reset state to enter into |
| + * |
| + * |
| + * Sets the PCI-E reset state for the device. This is the default |
| + * implementation. Architecture implementations can override this. |
| + */ |
| +int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, |
| + enum pcie_reset_state state) |
| +{ |
| + return -EINVAL; |
| +} |
| + |
| +/** |
| + * pci_set_pcie_reset_state - set reset state for device dev |
| + * @dev: the PCI-E device reset |
| + * @state: Reset state to enter into |
| + * |
| + * |
| + * Sets the PCI reset state for the device. |
| + */ |
| +int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) |
| +{ |
| + return pcibios_set_pcie_reset_state(dev, state); |
| +} |
| + |
| +/** |
| * pci_enable_wake - enable PCI device as wakeup event source |
| * @dev: PCI device affected |
| * @state: PCI state from which device will issue wakeup events |
| @@ -1427,4 +1455,5 @@ EXPORT_SYMBOL(pci_set_power_state); |
| EXPORT_SYMBOL(pci_save_state); |
| EXPORT_SYMBOL(pci_restore_state); |
| EXPORT_SYMBOL(pci_enable_wake); |
| +EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); |
| |
| --- a/include/linux/pci.h |
| +++ b/include/linux/pci.h |
| @@ -96,6 +96,19 @@ enum pci_channel_state { |
| pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, |
| }; |
| |
| +typedef unsigned int __bitwise pcie_reset_state_t; |
| + |
| +enum pcie_reset_state { |
| + /* Reset is NOT asserted (Use to deassert reset) */ |
| + pcie_deassert_reset = (__force pcie_reset_state_t) 1, |
| + |
| + /* Use #PERST to reset PCI-E device */ |
| + pcie_warm_reset = (__force pcie_reset_state_t) 2, |
| + |
| + /* Use PCI-E Hot Reset to reset device */ |
| + pcie_hot_reset = (__force pcie_reset_state_t) 3 |
| +}; |
| + |
| typedef unsigned short __bitwise pci_bus_flags_t; |
| enum pci_bus_flags { |
| PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, |
| @@ -532,6 +545,7 @@ static inline int pci_is_managed(struct |
| |
| void pci_disable_device(struct pci_dev *dev); |
| void pci_set_master(struct pci_dev *dev); |
| +int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); |
| #define HAVE_PCI_SET_MWI |
| int __must_check pci_set_mwi(struct pci_dev *dev); |
| void pci_clear_mwi(struct pci_dev *dev); |