aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2013-01-21 16:20:42 -0500
committerBjorn Helgaas <bhelgaas@google.com>2013-01-25 13:30:47 -0500
commit1f96a965e30d097a25818196e33d2dce923973a7 (patch)
treeeaaa813c0d73c791522f0f16168a83010abb2c0b /drivers/pci
parenta2766602ac6885f9514abd97821984cd152cdad3 (diff)
PCI: acpiphp: Add is_hotplug_bridge detection
When system support hotplug bridge with children hotplug slots, we need to make sure that parent bridge get preallocated resource so later when device is plugged into children slot, those children devices will get resource allocated. We do not meet this problem, because for PCIe hotplug card, when acpiphp is used, pci_scan_bridge will set that for us when detect hotplug bit in slot cap. Reported-and-tested-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Jason Baron <jbaron@redhat.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 9e2b1f6dbe41..b94879d20630 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot)
797 } 797 }
798} 798}
799 799
800static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev)
801{
802 struct acpiphp_func *func;
803
804 if (!dev->subordinate)
805 return;
806
807 /* quirk, or pcie could set it already */
808 if (dev->is_hotplug_bridge)
809 return;
810
811 if (PCI_SLOT(dev->devfn) != slot->device)
812 return;
813
814 list_for_each_entry(func, &slot->funcs, sibling) {
815 if (PCI_FUNC(dev->devfn) == func->function) {
816 /* check if this bridge has ejectable slots */
817 if ((detect_ejectable_slots(func->handle) > 0))
818 dev->is_hotplug_bridge = 1;
819 break;
820 }
821 }
822}
800/** 823/**
801 * enable_device - enable, configure a slot 824 * enable_device - enable, configure a slot
802 * @slot: slot to be enabled 825 * @slot: slot to be enabled
@@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot)
831 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 854 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
832 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 855 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
833 max = pci_scan_bridge(bus, dev, max, pass); 856 max = pci_scan_bridge(bus, dev, max, pass);
834 if (pass && dev->subordinate) 857 if (pass && dev->subordinate) {
858 check_hotplug_bridge(slot, dev);
835 pci_bus_size_bridges(dev->subordinate); 859 pci_bus_size_bridges(dev->subordinate);
860 }
836 } 861 }
837 } 862 }
838 } 863 }