diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 53 | ||||
-rw-r--r-- | drivers/pci/pci.h | 5 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 8 |
3 files changed, 46 insertions, 20 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 716aa93fff76..59df8575a48c 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -61,6 +61,7 @@ static DEFINE_MUTEX(bridge_mutex); | |||
61 | static void handle_hotplug_event_bridge (acpi_handle, u32, void *); | 61 | static void handle_hotplug_event_bridge (acpi_handle, u32, void *); |
62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); | 62 | static void acpiphp_sanitize_bus(struct pci_bus *bus); |
63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); | 63 | static void acpiphp_set_hpp_values(struct pci_bus *bus); |
64 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context); | ||
64 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); | 65 | static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context); |
65 | static void free_bridge(struct kref *kref); | 66 | static void free_bridge(struct kref *kref); |
66 | 67 | ||
@@ -147,7 +148,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, | |||
147 | 148 | ||
148 | 149 | ||
149 | static const struct acpi_dock_ops acpiphp_dock_ops = { | 150 | static const struct acpi_dock_ops acpiphp_dock_ops = { |
150 | .handler = handle_hotplug_event_func, | 151 | .handler = hotplug_event_func, |
151 | }; | 152 | }; |
152 | 153 | ||
153 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ | 154 | /* Check whether the PCI device is managed by native PCIe hotplug driver */ |
@@ -179,6 +180,20 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) | |||
179 | return true; | 180 | return true; |
180 | } | 181 | } |
181 | 182 | ||
183 | static void acpiphp_dock_init(void *data) | ||
184 | { | ||
185 | struct acpiphp_func *func = data; | ||
186 | |||
187 | get_bridge(func->slot->bridge); | ||
188 | } | ||
189 | |||
190 | static void acpiphp_dock_release(void *data) | ||
191 | { | ||
192 | struct acpiphp_func *func = data; | ||
193 | |||
194 | put_bridge(func->slot->bridge); | ||
195 | } | ||
196 | |||
182 | /* callback routine to register each ACPI PCI slot object */ | 197 | /* callback routine to register each ACPI PCI slot object */ |
183 | static acpi_status | 198 | static acpi_status |
184 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | 199 | register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) |
@@ -298,7 +313,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
298 | */ | 313 | */ |
299 | newfunc->flags &= ~FUNC_HAS_EJ0; | 314 | newfunc->flags &= ~FUNC_HAS_EJ0; |
300 | if (register_hotplug_dock_device(handle, | 315 | if (register_hotplug_dock_device(handle, |
301 | &acpiphp_dock_ops, newfunc)) | 316 | &acpiphp_dock_ops, newfunc, |
317 | acpiphp_dock_init, acpiphp_dock_release)) | ||
302 | dbg("failed to register dock device\n"); | 318 | dbg("failed to register dock device\n"); |
303 | 319 | ||
304 | /* we need to be notified when dock events happen | 320 | /* we need to be notified when dock events happen |
@@ -670,6 +686,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
670 | struct pci_bus *bus = slot->bridge->pci_bus; | 686 | struct pci_bus *bus = slot->bridge->pci_bus; |
671 | struct acpiphp_func *func; | 687 | struct acpiphp_func *func; |
672 | int num, max, pass; | 688 | int num, max, pass; |
689 | LIST_HEAD(add_list); | ||
673 | 690 | ||
674 | if (slot->flags & SLOT_ENABLED) | 691 | if (slot->flags & SLOT_ENABLED) |
675 | goto err_exit; | 692 | goto err_exit; |
@@ -694,13 +711,15 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
694 | max = pci_scan_bridge(bus, dev, max, pass); | 711 | max = pci_scan_bridge(bus, dev, max, pass); |
695 | if (pass && dev->subordinate) { | 712 | if (pass && dev->subordinate) { |
696 | check_hotplug_bridge(slot, dev); | 713 | check_hotplug_bridge(slot, dev); |
697 | pci_bus_size_bridges(dev->subordinate); | 714 | pcibios_resource_survey_bus(dev->subordinate); |
715 | __pci_bus_size_bridges(dev->subordinate, | ||
716 | &add_list); | ||
698 | } | 717 | } |
699 | } | 718 | } |
700 | } | 719 | } |
701 | } | 720 | } |
702 | 721 | ||
703 | pci_bus_assign_resources(bus); | 722 | __pci_bus_assign_resources(bus, &add_list, NULL); |
704 | acpiphp_sanitize_bus(bus); | 723 | acpiphp_sanitize_bus(bus); |
705 | acpiphp_set_hpp_values(bus); | 724 | acpiphp_set_hpp_values(bus); |
706 | acpiphp_set_acpi_region(slot); | 725 | acpiphp_set_acpi_region(slot); |
@@ -1065,22 +1084,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
1065 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); | 1084 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
1066 | } | 1085 | } |
1067 | 1086 | ||
1068 | static void _handle_hotplug_event_func(struct work_struct *work) | 1087 | static void hotplug_event_func(acpi_handle handle, u32 type, void *context) |
1069 | { | 1088 | { |
1070 | struct acpiphp_func *func; | 1089 | struct acpiphp_func *func = context; |
1071 | char objname[64]; | 1090 | char objname[64]; |
1072 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1091 | struct acpi_buffer buffer = { .length = sizeof(objname), |
1073 | .pointer = objname }; | 1092 | .pointer = objname }; |
1074 | struct acpi_hp_work *hp_work; | ||
1075 | acpi_handle handle; | ||
1076 | u32 type; | ||
1077 | |||
1078 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
1079 | handle = hp_work->handle; | ||
1080 | type = hp_work->type; | ||
1081 | func = (struct acpiphp_func *)hp_work->context; | ||
1082 | |||
1083 | acpi_scan_lock_acquire(); | ||
1084 | 1093 | ||
1085 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 1094 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); |
1086 | 1095 | ||
@@ -1113,6 +1122,18 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
1113 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); | 1122 | warn("notify_handler: unknown event type 0x%x for %s\n", type, objname); |
1114 | break; | 1123 | break; |
1115 | } | 1124 | } |
1125 | } | ||
1126 | |||
1127 | static void _handle_hotplug_event_func(struct work_struct *work) | ||
1128 | { | ||
1129 | struct acpi_hp_work *hp_work; | ||
1130 | struct acpiphp_func *func; | ||
1131 | |||
1132 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
1133 | func = hp_work->context; | ||
1134 | acpi_scan_lock_acquire(); | ||
1135 | |||
1136 | hotplug_event_func(hp_work->handle, hp_work->type, func); | ||
1116 | 1137 | ||
1117 | acpi_scan_lock_release(); | 1138 | acpi_scan_lock_release(); |
1118 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ | 1139 | kfree(hp_work); /* allocated in handle_hotplug_event_func */ |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 68678ed76b0d..d1182c4a754e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -202,6 +202,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
202 | struct resource *res, unsigned int reg); | 202 | struct resource *res, unsigned int reg); |
203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); | 203 | int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type); |
204 | void pci_configure_ari(struct pci_dev *dev); | 204 | void pci_configure_ari(struct pci_dev *dev); |
205 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | ||
206 | struct list_head *realloc_head); | ||
207 | void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | ||
208 | struct list_head *realloc_head, | ||
209 | struct list_head *fail_head); | ||
205 | 210 | ||
206 | /** | 211 | /** |
207 | * pci_ari_enabled - query ARI forwarding status | 212 | * pci_ari_enabled - query ARI forwarding status |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 16abaaa1f83c..d254e2379533 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -1044,7 +1044,7 @@ handle_done: | |||
1044 | ; | 1044 | ; |
1045 | } | 1045 | } |
1046 | 1046 | ||
1047 | static void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 1047 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
1048 | struct list_head *realloc_head) | 1048 | struct list_head *realloc_head) |
1049 | { | 1049 | { |
1050 | struct pci_dev *dev; | 1050 | struct pci_dev *dev; |
@@ -1115,9 +1115,9 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
1115 | } | 1115 | } |
1116 | EXPORT_SYMBOL(pci_bus_size_bridges); | 1116 | EXPORT_SYMBOL(pci_bus_size_bridges); |
1117 | 1117 | ||
1118 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 1118 | void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
1119 | struct list_head *realloc_head, | 1119 | struct list_head *realloc_head, |
1120 | struct list_head *fail_head) | 1120 | struct list_head *fail_head) |
1121 | { | 1121 | { |
1122 | struct pci_bus *b; | 1122 | struct pci_bus *b; |
1123 | struct pci_dev *dev; | 1123 | struct pci_dev *dev; |