diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index b2255736ac81..51f56ef4ab6f 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -749,6 +749,37 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
749 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 749 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
750 | } | 750 | } |
751 | 751 | ||
752 | /* | ||
753 | * pciehp has a 1:1 bus:slot relationship so we ultimately want a secondary | ||
754 | * bus reset of the bridge, but if the slot supports surprise removal we need | ||
755 | * to disable presence detection around the bus reset and clear any spurious | ||
756 | * events after. | ||
757 | */ | ||
758 | int pciehp_reset_slot(struct slot *slot, int probe) | ||
759 | { | ||
760 | struct controller *ctrl = slot->ctrl; | ||
761 | |||
762 | if (probe) | ||
763 | return 0; | ||
764 | |||
765 | if (HP_SUPR_RM(ctrl)) { | ||
766 | pcie_write_cmd(ctrl, 0, PCI_EXP_SLTCTL_PDCE); | ||
767 | if (pciehp_poll_mode) | ||
768 | del_timer_sync(&ctrl->poll_timer); | ||
769 | } | ||
770 | |||
771 | pci_reset_bridge_secondary_bus(ctrl->pcie->port); | ||
772 | |||
773 | if (HP_SUPR_RM(ctrl)) { | ||
774 | pciehp_writew(ctrl, PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDC); | ||
775 | pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PDCE, PCI_EXP_SLTCTL_PDCE); | ||
776 | if (pciehp_poll_mode) | ||
777 | int_poll_timeout(ctrl->poll_timer.data); | ||
778 | } | ||
779 | |||
780 | return 0; | ||
781 | } | ||
782 | |||
752 | int pcie_init_notification(struct controller *ctrl) | 783 | int pcie_init_notification(struct controller *ctrl) |
753 | { | 784 | { |
754 | if (pciehp_request_irq(ctrl)) | 785 | if (pciehp_request_irq(ctrl)) |