diff options
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r-- | drivers/pci/pci-acpi.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index bc01d34e2634..f94c86fbc669 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -1,9 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * File: pci-acpi.c | 2 | * File: pci-acpi.c |
3 | * Purpose: Provide PCI supports in ACPI | 3 | * Purpose: Provide PCI support in ACPI |
4 | * | 4 | * |
5 | * Copyright (C) 2004 Intel | 5 | * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com> |
6 | * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) | 6 | * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com> |
7 | * Copyright (C) 2004 Intel Corp. | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
@@ -207,3 +208,53 @@ acpi_status pci_osc_control_set(u32 flags) | |||
207 | return status; | 208 | return status; |
208 | } | 209 | } |
209 | EXPORT_SYMBOL(pci_osc_control_set); | 210 | EXPORT_SYMBOL(pci_osc_control_set); |
211 | |||
212 | /* ACPI bus type */ | ||
213 | static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) | ||
214 | { | ||
215 | struct pci_dev * pci_dev; | ||
216 | acpi_integer addr; | ||
217 | |||
218 | pci_dev = to_pci_dev(dev); | ||
219 | /* Please ref to ACPI spec for the syntax of _ADR */ | ||
220 | addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); | ||
221 | *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); | ||
222 | if (!*handle) | ||
223 | return -ENODEV; | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle) | ||
228 | { | ||
229 | int num; | ||
230 | unsigned int seg, bus; | ||
231 | |||
232 | /* | ||
233 | * The string should be the same as root bridge's name | ||
234 | * Please look at 'pci_scan_bus_parented' | ||
235 | */ | ||
236 | num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus); | ||
237 | if (num != 2) | ||
238 | return -ENODEV; | ||
239 | *handle = acpi_get_pci_rootbridge_handle(seg, bus); | ||
240 | if (!*handle) | ||
241 | return -ENODEV; | ||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static struct acpi_bus_type pci_acpi_bus = { | ||
246 | .bus = &pci_bus_type, | ||
247 | .find_device = pci_acpi_find_device, | ||
248 | .find_bridge = pci_acpi_find_root_bridge, | ||
249 | }; | ||
250 | |||
251 | static int __init pci_acpi_init(void) | ||
252 | { | ||
253 | int ret; | ||
254 | |||
255 | ret = register_acpi_bus_type(&pci_acpi_bus); | ||
256 | if (ret) | ||
257 | return 0; | ||
258 | return 0; | ||
259 | } | ||
260 | arch_initcall(pci_acpi_init); | ||