diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/pci_bind.c | 16 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 24 |
2 files changed, 38 insertions, 2 deletions
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 5d19b39e9e2b..7753df1f9fb8 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c | |||
@@ -129,6 +129,8 @@ acpi_pci_bind ( | |||
129 | char *pathname = NULL; | 129 | char *pathname = NULL; |
130 | struct acpi_buffer buffer = {0, NULL}; | 130 | struct acpi_buffer buffer = {0, NULL}; |
131 | acpi_handle handle = NULL; | 131 | acpi_handle handle = NULL; |
132 | struct pci_dev *dev; | ||
133 | struct pci_bus *bus; | ||
132 | 134 | ||
133 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); | 135 | ACPI_FUNCTION_TRACE("acpi_pci_bind"); |
134 | 136 | ||
@@ -193,8 +195,20 @@ acpi_pci_bind ( | |||
193 | * Locate matching device in PCI namespace. If it doesn't exist | 195 | * Locate matching device in PCI namespace. If it doesn't exist |
194 | * this typically means that the device isn't currently inserted | 196 | * this typically means that the device isn't currently inserted |
195 | * (e.g. docking station, port replicator, etc.). | 197 | * (e.g. docking station, port replicator, etc.). |
198 | * We cannot simply search the global pci device list, since | ||
199 | * PCI devices are added to the global pci list when the root | ||
200 | * bridge start ops are run, which may not have happened yet. | ||
196 | */ | 201 | */ |
197 | data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); | 202 | bus = pci_find_bus(data->id.segment, data->id.bus); |
203 | if (bus) { | ||
204 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
205 | if (dev->devfn == PCI_DEVFN(data->id.device, | ||
206 | data->id.function)) { | ||
207 | data->dev = dev; | ||
208 | break; | ||
209 | } | ||
210 | } | ||
211 | } | ||
198 | if (!data->dev) { | 212 | if (!data->dev) { |
199 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 213 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
200 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", | 214 | "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7e6b8e3b2ed4..5d2f77fcd50c 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root") | |||
46 | 46 | ||
47 | static int acpi_pci_root_add (struct acpi_device *device); | 47 | static int acpi_pci_root_add (struct acpi_device *device); |
48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); | 48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); |
49 | static int acpi_pci_root_start (struct acpi_device *device); | ||
49 | 50 | ||
50 | static struct acpi_driver acpi_pci_root_driver = { | 51 | static struct acpi_driver acpi_pci_root_driver = { |
51 | .name = ACPI_PCI_ROOT_DRIVER_NAME, | 52 | .name = ACPI_PCI_ROOT_DRIVER_NAME, |
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
54 | .ops = { | 55 | .ops = { |
55 | .add = acpi_pci_root_add, | 56 | .add = acpi_pci_root_add, |
56 | .remove = acpi_pci_root_remove, | 57 | .remove = acpi_pci_root_remove, |
58 | .start = acpi_pci_root_start, | ||
57 | }, | 59 | }, |
58 | }; | 60 | }; |
59 | 61 | ||
@@ -169,6 +171,7 @@ acpi_pci_root_add ( | |||
169 | if (!root) | 171 | if (!root) |
170 | return_VALUE(-ENOMEM); | 172 | return_VALUE(-ENOMEM); |
171 | memset(root, 0, sizeof(struct acpi_pci_root)); | 173 | memset(root, 0, sizeof(struct acpi_pci_root)); |
174 | INIT_LIST_HEAD(&root->node); | ||
172 | 175 | ||
173 | root->handle = device->handle; | 176 | root->handle = device->handle; |
174 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 177 | strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); |
@@ -298,12 +301,31 @@ acpi_pci_root_add ( | |||
298 | root->id.bus); | 301 | root->id.bus); |
299 | 302 | ||
300 | end: | 303 | end: |
301 | if (result) | 304 | if (result) { |
305 | if (!list_empty(&root->node)) | ||
306 | list_del(&root->node); | ||
302 | kfree(root); | 307 | kfree(root); |
308 | } | ||
303 | 309 | ||
304 | return_VALUE(result); | 310 | return_VALUE(result); |
305 | } | 311 | } |
306 | 312 | ||
313 | static int | ||
314 | acpi_pci_root_start ( | ||
315 | struct acpi_device *device) | ||
316 | { | ||
317 | struct acpi_pci_root *root; | ||
318 | |||
319 | ACPI_FUNCTION_TRACE("acpi_pci_root_start"); | ||
320 | |||
321 | list_for_each_entry(root, &acpi_pci_roots, node) { | ||
322 | if (root->handle == device->handle) { | ||
323 | pci_bus_add_devices(root->bus); | ||
324 | return_VALUE(0); | ||
325 | } | ||
326 | } | ||
327 | return_VALUE(-ENODEV); | ||
328 | } | ||
307 | 329 | ||
308 | static int | 330 | static int |
309 | acpi_pci_root_remove ( | 331 | acpi_pci_root_remove ( |