diff options
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r-- | drivers/acpi/pci_root.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index a860efa2c562..4ecf701687e8 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -117,6 +117,19 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
117 | 117 | ||
118 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 118 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
119 | 119 | ||
120 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | ||
121 | { | ||
122 | struct acpi_pci_root *tmp; | ||
123 | |||
124 | list_for_each_entry(tmp, &acpi_pci_roots, node) { | ||
125 | if ((tmp->id.segment == (u16) seg) && (tmp->id.bus == (u16) bus)) | ||
126 | return tmp->device->handle; | ||
127 | } | ||
128 | return NULL; | ||
129 | } | ||
130 | |||
131 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | ||
132 | |||
120 | static acpi_status | 133 | static acpi_status |
121 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 134 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) |
122 | { | 135 | { |
@@ -152,6 +165,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) | |||
152 | return AE_OK; | 165 | return AE_OK; |
153 | } | 166 | } |
154 | 167 | ||
168 | static void acpi_pci_bridge_scan(struct acpi_device *device) | ||
169 | { | ||
170 | int status; | ||
171 | struct acpi_device *child = NULL; | ||
172 | |||
173 | if (device->flags.bus_address) | ||
174 | if (device->parent && device->parent->ops.bind) { | ||
175 | status = device->parent->ops.bind(device); | ||
176 | if (!status) { | ||
177 | list_for_each_entry(child, &device->children, node) | ||
178 | acpi_pci_bridge_scan(child); | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | |||
155 | static int acpi_pci_root_add(struct acpi_device *device) | 183 | static int acpi_pci_root_add(struct acpi_device *device) |
156 | { | 184 | { |
157 | int result = 0; | 185 | int result = 0; |
@@ -160,6 +188,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
160 | acpi_status status = AE_OK; | 188 | acpi_status status = AE_OK; |
161 | unsigned long value = 0; | 189 | unsigned long value = 0; |
162 | acpi_handle handle = NULL; | 190 | acpi_handle handle = NULL; |
191 | struct acpi_device *child; | ||
163 | 192 | ||
164 | 193 | ||
165 | if (!device) | 194 | if (!device) |
@@ -175,9 +204,6 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
175 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 204 | strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); |
176 | acpi_driver_data(device) = root; | 205 | acpi_driver_data(device) = root; |
177 | 206 | ||
178 | /* | ||
179 | * TBD: Doesn't the bus driver automatically set this? | ||
180 | */ | ||
181 | device->ops.bind = acpi_pci_bind; | 207 | device->ops.bind = acpi_pci_bind; |
182 | 208 | ||
183 | /* | 209 | /* |
@@ -299,6 +325,12 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
299 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, | 325 | result = acpi_pci_irq_add_prt(device->handle, root->id.segment, |
300 | root->id.bus); | 326 | root->id.bus); |
301 | 327 | ||
328 | /* | ||
329 | * Scan and bind all _ADR-Based Devices | ||
330 | */ | ||
331 | list_for_each_entry(child, &device->children, node) | ||
332 | acpi_pci_bridge_scan(child); | ||
333 | |||
302 | end: | 334 | end: |
303 | if (result) { | 335 | if (result) { |
304 | if (!list_empty(&root->node)) | 336 | if (!list_empty(&root->node)) |