[ACPI] Bind ACPI and PCI devices
authorDavid Shaohua Li <shaohua.li@intel.com>
Fri, 18 Mar 2005 23:53:36 +0000 (18:53 -0500)
committerLen Brown <len.brown@intel.com>
Tue, 12 Jul 2005 03:45:24 +0000 (23:45 -0400)
http://bugzilla.kernel.org/show_bug.cgi?id=4277

Signed-off-by: David Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/pci/pci-acpi.c

index bc01d34..f94c86f 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * File:       pci-acpi.c
- * Purpose:    Provide PCI supports in ACPI
+ * Purpose:    Provide PCI support in ACPI
  *
- * Copyright (C) 2004 Intel
- * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
+ * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com>
+ * Copyright (C) 2004 Intel Corp.
  */
 
 #include <linux/delay.h>
@@ -207,3 +208,53 @@ acpi_status pci_osc_control_set(u32 flags)
        return status;
 }
 EXPORT_SYMBOL(pci_osc_control_set);
+
+/* ACPI bus type */
+static int pci_acpi_find_device(struct device *dev, acpi_handle *handle)
+{
+       struct pci_dev * pci_dev;
+       acpi_integer    addr;
+
+       pci_dev = to_pci_dev(dev);
+       /* Please ref to ACPI spec for the syntax of _ADR */
+       addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+       *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr);
+       if (!*handle)
+               return -ENODEV;
+       return 0;
+}
+
+static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle)
+{
+       int num;
+       unsigned int seg, bus;
+
+       /*
+        * The string should be the same as root bridge's name
+        * Please look at 'pci_scan_bus_parented'
+        */
+       num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus);
+       if (num != 2)
+               return -ENODEV;
+       *handle = acpi_get_pci_rootbridge_handle(seg, bus);
+       if (!*handle)
+               return -ENODEV;
+       return 0;
+}
+
+static struct acpi_bus_type pci_acpi_bus = {
+       .bus = &pci_bus_type,
+       .find_device = pci_acpi_find_device,
+       .find_bridge = pci_acpi_find_root_bridge,
+};
+
+static int __init pci_acpi_init(void)
+{
+       int ret;
+
+       ret = register_acpi_bus_type(&pci_acpi_bus);
+       if (ret)
+               return 0;
+       return 0;
+}
+arch_initcall(pci_acpi_init);