The following patch adds a generic API to assert and deassert PCI reset to a device on a pSeries machine. This is needed to solve an issue with a new ipr PCI-E adapter which causes EEH errors when running BIST. The only way to reset this adapter without causing an EEH error is to use PCI reset. Signed-off-by: Brian King --- linux-2.6-bjking1/arch/powerpc/platforms/pseries/eeh.c | 42 +++++++++++++++++ linux-2.6-bjking1/include/asm-powerpc/ppc-pci.h | 3 + 2 files changed, 45 insertions(+) diff -puN arch/powerpc/platforms/pseries/eeh.c~powerpc_slot_reset_api arch/powerpc/platforms/pseries/eeh.c --- linux-2.6/arch/powerpc/platforms/pseries/eeh.c~powerpc_slot_reset_api 2006-12-18 15:58:56.000000000 -0600 +++ linux-2.6-bjking1/arch/powerpc/platforms/pseries/eeh.c 2006-12-18 15:58:57.000000000 -0600 @@ -591,6 +591,48 @@ static void __rtas_set_slot_reset(struct msleep (PCI_BUS_SETTLE_TIME_MSEC); } +/** + * pci_set_slot_reset - Assert PCI reset to the PCI slot + * @dev: pci device struct + * + * After asserting PCI reset, the caller should wait for + * 100 milliseconds or longer. + * + * Return value: + * 0 if success + **/ +int pci_set_slot_reset(struct pci_dev *dev) +{ + struct device_node *dn = pci_device_to_OF_node(dev); + struct pci_dn *pdn = PCI_DN(dn); + + rtas_pci_slot_reset(pdn, 1); + return 0; +} +EXPORT_SYMBOL_GPL(pci_set_slot_reset); + +/** + * pci_clear_slot_reset - Clear PCI reset to the PCI slot + * @dev: pci device struct + * + * After clearing PCI reset, the caller should wait 1.8 seconds + * or longer for the bus to stabilize and the device to come + * ready. + * + * Return value: + * 0 if success + **/ +int pci_clear_slot_reset(struct pci_dev *dev) +{ + struct device_node *dn = pci_device_to_OF_node(dev); + struct pci_dn *pdn = PCI_DN(dn); + + eeh_clear_slot (pdn->node, EEH_MODE_ISOLATED); + rtas_pci_slot_reset (pdn, 0); + return 0; +} +EXPORT_SYMBOL_GPL(pci_clear_slot_reset); + int rtas_set_slot_reset(struct pci_dn *pdn) { int i, rc; diff -puN include/asm-powerpc/ppc-pci.h~powerpc_slot_reset_api include/asm-powerpc/ppc-pci.h --- linux-2.6/include/asm-powerpc/ppc-pci.h~powerpc_slot_reset_api 2006-12-18 15:58:56.000000000 -0600 +++ linux-2.6-bjking1/include/asm-powerpc/ppc-pci.h 2006-12-18 15:58:57.000000000 -0600 @@ -124,6 +124,9 @@ void eeh_clear_slot (struct device_node /* Find the associated "Partiationable Endpoint" PE */ struct device_node * find_device_pe(struct device_node *dn); +int pci_set_slot_reset(struct pci_dev *dev); +int pci_clear_slot_reset(struct pci_dev *dev); + #endif #endif /* __KERNEL__ */ _