/* Called during PCI resource reassignment */
        resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type);
 
+       /* Reset the secondary bus of bridge */
+       void  (*pcibios_reset_secondary_bus)(struct pci_dev *dev);
+
        /* Called to shutdown machine specific hardware not already controlled
         * by other drivers.
         */
 
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/of_address.h>
 #include <linux/of_pci.h>
        return 1;
 }
 
+void pcibios_reset_secondary_bus(struct pci_dev *dev)
+{
+       u16 ctrl;
+
+       if (ppc_md.pcibios_reset_secondary_bus) {
+               ppc_md.pcibios_reset_secondary_bus(dev);
+               return;
+       }
+
+       pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &ctrl);
+       ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
+       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
+       msleep(2);
+
+       ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
+       pci_write_config_word(dev, PCI_BRIDGE_CONTROL, ctrl);
+       ssleep(1);
+}
+
 static resource_size_t pcibios_io_size(const struct pci_controller *hose)
 {
 #ifdef CONFIG_PPC64
 
 
 {
        struct device_node *dn = pci_device_to_OF_node(dev);
+       struct eeh_dev *edev = of_node_to_eeh_dev(dn);
+       int aer = edev ? edev->aer_cap : 0;
        u32 ctrl;
 
        pr_debug("%s: Reset PCI bus %04x:%02x with option %d\n",
        switch (option) {
        case EEH_RESET_FUNDAMENTAL:
        case EEH_RESET_HOT:
+               /* Don't report linkDown event */
+               if (aer) {
+                       eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
+                                            4, &ctrl);
+                       ctrl |= PCI_ERR_UNC_SURPDN;
+                        eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
+                                             4, ctrl);
+                }
+
                eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
                ctrl |= PCI_BRIDGE_CTL_BUS_RESET;
                eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
-
                msleep(EEH_PE_RST_HOLD_TIME);
+
                break;
        case EEH_RESET_DEACTIVATE:
                eeh_ops->read_config(dn, PCI_BRIDGE_CONTROL, 2, &ctrl);
                ctrl &= ~PCI_BRIDGE_CTL_BUS_RESET;
                eeh_ops->write_config(dn, PCI_BRIDGE_CONTROL, 2, ctrl);
-
                msleep(EEH_PE_RST_SETTLE_TIME);
+
+               /* Continue reporting linkDown event */
+               if (aer) {
+                       eeh_ops->read_config(dn, aer + PCI_ERR_UNCOR_MASK,
+                                            4, &ctrl);
+                       ctrl &= ~PCI_ERR_UNC_SURPDN;
+                       eeh_ops->write_config(dn, aer + PCI_ERR_UNCOR_MASK,
+                                             4, ctrl);
+               }
+
                break;
        }
 
        return 0;
 }
 
+void pnv_pci_reset_secondary_bus(struct pci_dev *dev)
+{
+       struct pci_controller *hose;
+
+       if (pci_is_root_bus(dev->bus)) {
+               hose = pci_bus_to_host(dev->bus);
+               ioda_eeh_root_reset(hose, EEH_RESET_HOT);
+               ioda_eeh_root_reset(hose, EEH_RESET_DEACTIVATE);
+       } else {
+               ioda_eeh_bridge_reset(dev, EEH_RESET_HOT);
+               ioda_eeh_bridge_reset(dev, EEH_RESET_DEACTIVATE);
+       }
+}
+
 /**
  * ioda_eeh_reset - Reset the indicated PE
  * @pe: EEH PE
 
        ppc_md.pcibios_fixup = pnv_pci_ioda_fixup;
        ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
        ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
+       ppc_md.pcibios_reset_secondary_bus = pnv_pci_reset_secondary_bus;
        pci_add_flags(PCI_REASSIGN_ALL_RSRC);
 
        /* Reset IODA tables to a clean state */
 
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
                                        __be64 *startp, __be64 *endp, bool rm);
+extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
 
 #endif /* __POWERNV_PCI_H */
 
        return 0;
 }
 
-/**
- * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge.
- * @dev: Bridge device
- *
- * Use the bridge control register to assert reset on the secondary bus.
- * Devices on the secondary bus are left in power-on state.
- */
-void pci_reset_bridge_secondary_bus(struct pci_dev *dev)
+void __weak pcibios_reset_secondary_bus(struct pci_dev *dev)
 {
        u16 ctrl;
 
         */
        ssleep(1);
 }
+
+/**
+ * pci_reset_bridge_secondary_bus - Reset the secondary bus on a PCI bridge.
+ * @dev: Bridge device
+ *
+ * Use the bridge control register to assert reset on the secondary bus.
+ * Devices on the secondary bus are left in power-on state.
+ */
+void pci_reset_bridge_secondary_bus(struct pci_dev *dev)
+{
+       pcibios_reset_secondary_bus(dev);
+}
 EXPORT_SYMBOL_GPL(pci_reset_bridge_secondary_bus);
 
 static int pci_parent_bus_reset(struct pci_dev *dev, int probe)