[PATCH/RFC 3/4]An implementation for PCI bus

From: Li Shaohua
Date: Sun Nov 07 2004 - 23:23:50 EST


Hi,
An implementation to bind PCI devices with ACPI devices


Thanks,
Shaohua
---

2.6-root/drivers/pci/pci-driver.c | 52
++++++++++++++++++++++++++++++++++++++
1 files changed, 52 insertions(+)

diff -puN drivers/pci/pci-driver.c~pci-bind-acpi
drivers/pci/pci-driver.c
--- 2.6/drivers/pci/pci-driver.c~pci-bind-acpi 2004-11-08
11:06:53.249197784 +0800
+++ 2.6-root/drivers/pci/pci-driver.c 2004-11-08 11:08:50.244411808
+0800
@@ -530,12 +530,64 @@ int pci_hotplug (struct device *dev, cha
}
#endif

+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+int pci_device_platform_bind(struct device *dev)
+{
+ struct pci_dev * pci_dev;
+ acpi_handle parent_handle = NULL;
+ acpi_integer address;
+
+ pci_dev = to_pci_dev(dev);
+ if (!pci_dev->bus->parent) {
+ /* It's device under root bridge
+ * This is a little ugly, but now root bridge
+ * is added in special way.
+ */
+ parent_handle = acpi_get_rootbridge_handle(
+ pci_domain_nr(pci_dev->bus), pci_dev->bus->number);
+ } else {
+ if (dev->parent)
+ parent_handle = dev->parent->handle;
+ }
+ if (!parent_handle) {
+ printk("Can't find parent handle \n");
+ return -1;
+ }
+ /* Please ref to ACPI spec for syntax of _ADR */
+ address = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+ dev->handle = acpi_get_child(parent_handle, address);
+
+#if 1
+ {/* For Debug */
+ char name[80] = {'?','\0'};
+ struct acpi_buffer buffer = {sizeof(name), name};
+
+ printk("Device %s:", pci_name(pci_dev));
+ if (dev->handle) {
+ acpi_get_name(dev->handle, ACPI_FULL_PATHNAME, &buffer);
+ printk("%s", name);
+ }
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#else
+int pci_device_platform_bind(struct device *dev)
+{
+ return 0;
+}
+#endif
+
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.hotplug = pci_hotplug,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
+ .platform_bind = pci_device_platform_bind,
.dev_attrs = pci_dev_attrs,
};

_


A sample implementation to bind PCI devices with ACPI devices

---

2.6-root/drivers/pci/pci-driver.c | 52 ++++++++++++++++++++++++++++++++++++++
1 files changed, 52 insertions(+)

diff -puN drivers/pci/pci-driver.c~pci-bind-acpi drivers/pci/pci-driver.c
--- 2.6/drivers/pci/pci-driver.c~pci-bind-acpi 2004-11-08 11:06:53.249197784 +0800
+++ 2.6-root/drivers/pci/pci-driver.c 2004-11-08 11:08:50.244411808 +0800
@@ -530,12 +530,64 @@ int pci_hotplug (struct device *dev, cha
}
#endif

+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+int pci_device_platform_bind(struct device *dev)
+{
+ struct pci_dev * pci_dev;
+ acpi_handle parent_handle = NULL;
+ acpi_integer address;
+
+ pci_dev = to_pci_dev(dev);
+ if (!pci_dev->bus->parent) {
+ /* It's device under root bridge
+ * This is a little ugly, but now root bridge
+ * is added in special way.
+ */
+ parent_handle = acpi_get_rootbridge_handle(
+ pci_domain_nr(pci_dev->bus), pci_dev->bus->number);
+ } else {
+ if (dev->parent)
+ parent_handle = dev->parent->handle;
+ }
+ if (!parent_handle) {
+ printk("Can't find parent handle \n");
+ return -1;
+ }
+ /* Please ref to ACPI spec for syntax of _ADR */
+ address = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn);
+ dev->handle = acpi_get_child(parent_handle, address);
+
+#if 1
+ {/* For Debug */
+ char name[80] = {'?','\0'};
+ struct acpi_buffer buffer = {sizeof(name), name};
+
+ printk("Device %s:", pci_name(pci_dev));
+ if (dev->handle) {
+ acpi_get_name(dev->handle, ACPI_FULL_PATHNAME, &buffer);
+ printk("%s", name);
+ }
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#else
+int pci_device_platform_bind(struct device *dev)
+{
+ return 0;
+}
+#endif
+
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.hotplug = pci_hotplug,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
+ .platform_bind = pci_device_platform_bind,
.dev_attrs = pci_dev_attrs,
};

_