From fea2f357f839995fe36fba118ce535f13bbb52ee Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Tue, 15 Jan 2013 11:12:16 +0800 Subject: [PATCH] --- yaml --- r: 358398 b: refs/heads/master c: b0cc6020e1cc62f1253215f189611b34be4a83c7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/frv/mb93090-mb00/pci-frv.h | 1 + trunk/arch/frv/mb93090-mb00/pci-vdk.c | 4 +- trunk/arch/ia64/pci/pci.c | 8 - trunk/arch/mn10300/unit-asb2305/pci-asb2305.h | 1 + trunk/arch/mn10300/unit-asb2305/pci.c | 4 +- trunk/arch/x86/include/asm/pci.h | 3 - trunk/arch/x86/include/asm/pci_x86.h | 1 + trunk/arch/x86/pci/acpi.c | 9 - trunk/arch/x86/pci/common.c | 1 + trunk/arch/x86/pci/i386.c | 185 ++++++---------- trunk/arch/x86/pci/legacy.c | 2 +- trunk/arch/x86/pci/numaq_32.c | 2 +- trunk/drivers/acpi/Makefile | 2 +- trunk/drivers/acpi/acpi_memhotplug.c | 24 +- trunk/drivers/acpi/container.c | 31 ++- trunk/drivers/acpi/device_pm.c | 2 +- trunk/drivers/acpi/dock.c | 15 +- trunk/drivers/acpi/glue.c | 50 ++--- trunk/drivers/acpi/internal.h | 1 - trunk/drivers/acpi/pci_bind.c | 122 ++++++++++ trunk/drivers/acpi/pci_root.c | 89 ++++++-- trunk/drivers/acpi/processor_driver.c | 30 ++- trunk/drivers/acpi/scan.c | 208 +++++++++++------- trunk/drivers/pci/bus.c | 2 - trunk/drivers/pci/hotplug/acpiphp_glue.c | 40 ++-- trunk/drivers/pci/hotplug/cpqphp_ctrl.c | 57 +++-- trunk/drivers/pci/hotplug/sgi_hotplug.c | 6 +- trunk/drivers/pci/pci-acpi.c | 65 ++---- trunk/drivers/pci/pci.c | 52 ++++- trunk/drivers/pci/pci.h | 5 + trunk/drivers/pci/probe.c | 17 +- trunk/include/acpi/acpi_bus.h | 19 +- trunk/include/linux/acpi.h | 5 - trunk/include/linux/pci.h | 3 - 35 files changed, 643 insertions(+), 425 deletions(-) create mode 100644 trunk/drivers/acpi/pci_bind.c diff --git a/[refs] b/[refs] index 85224d1452a0..4862eda0f654 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 708b59bfe1d1727451ca41f5dc4c17cf99dfaf51 +refs/heads/master: b0cc6020e1cc62f1253215f189611b34be4a83c7 diff --git a/trunk/arch/frv/mb93090-mb00/pci-frv.h b/trunk/arch/frv/mb93090-mb00/pci-frv.h index 76c4e73d643d..089eeba4f3bc 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-frv.h +++ b/trunk/arch/frv/mb93090-mb00/pci-frv.h @@ -31,6 +31,7 @@ void pcibios_resource_survey(void); /* pci-vdk.c */ extern int __nongpreldata pcibios_last_bus; +extern struct pci_bus *__nongpreldata pci_root_bus; extern struct pci_ops *__nongpreldata pci_root_ops; /* pci-irq.c */ diff --git a/trunk/arch/frv/mb93090-mb00/pci-vdk.c b/trunk/arch/frv/mb93090-mb00/pci-vdk.c index 1152a1e3cabb..71e9bcf58105 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-vdk.c +++ b/trunk/arch/frv/mb93090-mb00/pci-vdk.c @@ -26,6 +26,7 @@ unsigned int __nongpreldata pci_probe = 1; int __nongpreldata pcibios_last_bus = -1; +struct pci_bus *__nongpreldata pci_root_bus; struct pci_ops *__nongpreldata pci_root_ops; /* @@ -415,7 +416,8 @@ int __init pcibios_init(void) printk("PCI: Probing PCI hardware\n"); pci_add_resource(&resources, &pci_ioport_resource); pci_add_resource(&resources, &pci_iomem_resource); - pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources); + pci_root_bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, + &resources); pcibios_irq_init(); pcibios_fixup_peer_bridges(); diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 00e59c7ad3c0..5faa66c5c2a8 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -396,14 +396,6 @@ pci_acpi_scan_root(struct acpi_pci_root *root) return NULL; } -int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) -{ - struct pci_controller *controller = bridge->bus->sysdata; - - ACPI_HANDLE_SET(&bridge->dev, controller->acpi_handle); - return 0; -} - static int __devinit is_valid_resource(struct pci_dev *dev, int idx) { unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; diff --git a/trunk/arch/mn10300/unit-asb2305/pci-asb2305.h b/trunk/arch/mn10300/unit-asb2305/pci-asb2305.h index 7fa66a0e4624..1194fe486b01 100644 --- a/trunk/arch/mn10300/unit-asb2305/pci-asb2305.h +++ b/trunk/arch/mn10300/unit-asb2305/pci-asb2305.h @@ -36,6 +36,7 @@ extern void pcibios_resource_survey(void); /* pci.c */ extern int pcibios_last_bus; +extern struct pci_bus *pci_root_bus; extern struct pci_ops *pci_root_ops; extern struct irq_routing_table *pcibios_get_irq_routing_table(void); diff --git a/trunk/arch/mn10300/unit-asb2305/pci.c b/trunk/arch/mn10300/unit-asb2305/pci.c index 426bf51605f3..e2059486d3f8 100644 --- a/trunk/arch/mn10300/unit-asb2305/pci.c +++ b/trunk/arch/mn10300/unit-asb2305/pci.c @@ -24,6 +24,7 @@ unsigned int pci_probe = 1; int pcibios_last_bus = -1; +struct pci_bus *pci_root_bus; struct pci_ops *pci_root_ops; /* @@ -376,7 +377,8 @@ static int __init pcibios_init(void) pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset); pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset); - pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources); + pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, + &resources); pcibios_irq_init(); pcibios_fixup_irqs(); diff --git a/trunk/arch/x86/include/asm/pci.h b/trunk/arch/x86/include/asm/pci.h index 9f437e97e9e8..dba7805176bf 100644 --- a/trunk/arch/x86/include/asm/pci.h +++ b/trunk/arch/x86/include/asm/pci.h @@ -14,9 +14,6 @@ struct pci_sysdata { int domain; /* PCI domain */ int node; /* NUMA node */ -#ifdef CONFIG_ACPI - void *acpi; /* ACPI-specific data */ -#endif #ifdef CONFIG_X86_64 void *iommu; /* IOMMU private data */ #endif diff --git a/trunk/arch/x86/include/asm/pci_x86.h b/trunk/arch/x86/include/asm/pci_x86.h index 0126f104f0a5..73e8eeff22ee 100644 --- a/trunk/arch/x86/include/asm/pci_x86.h +++ b/trunk/arch/x86/include/asm/pci_x86.h @@ -54,6 +54,7 @@ void pcibios_set_cache_line_size(void); /* pci-pc.c */ extern int pcibios_last_bus; +extern struct pci_bus *pci_root_bus; extern struct pci_ops pci_root_ops; void pcibios_scan_specific_bus(int busn); diff --git a/trunk/arch/x86/pci/acpi.c b/trunk/arch/x86/pci/acpi.c index 3d49094ed3e8..0c01261fe5a8 100644 --- a/trunk/arch/x86/pci/acpi.c +++ b/trunk/arch/x86/pci/acpi.c @@ -522,7 +522,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) sd = &info->sd; sd->domain = domain; sd->node = node; - sd->acpi = device->handle; /* * Maybe the desired pci bus has been already scanned. In such case * it is unnecessary to scan the pci bus with the given domain,busnum. @@ -594,14 +593,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) return bus; } -int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) -{ - struct pci_sysdata *sd = bridge->bus->sysdata; - - ACPI_HANDLE_SET(&bridge->dev, sd->acpi); - return 0; -} - int __init pci_acpi_init(void) { struct pci_dev *dev = NULL; diff --git a/trunk/arch/x86/pci/common.c b/trunk/arch/x86/pci/common.c index 505731b139f4..412e1286d1fc 100644 --- a/trunk/arch/x86/pci/common.c +++ b/trunk/arch/x86/pci/common.c @@ -34,6 +34,7 @@ int noioapicreroute = 1; #endif int pcibios_last_bus = -1; unsigned long pirq_table_addr; +struct pci_bus *pci_root_bus; const struct pci_raw_ops *__read_mostly raw_pci_ops; const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; diff --git a/trunk/arch/x86/pci/i386.c b/trunk/arch/x86/pci/i386.c index 94919e307f8e..dd8ca6f7223b 100644 --- a/trunk/arch/x86/pci/i386.c +++ b/trunk/arch/x86/pci/i386.c @@ -51,7 +51,6 @@ struct pcibios_fwaddrmap { static LIST_HEAD(pcibios_fwaddrmappings); static DEFINE_SPINLOCK(pcibios_fwaddrmap_lock); -static bool pcibios_fw_addr_done; /* Must be called with 'pcibios_fwaddrmap_lock' lock held. */ static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev) @@ -73,9 +72,6 @@ pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr) unsigned long flags; struct pcibios_fwaddrmap *map; - if (pcibios_fw_addr_done) - return; - spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); map = pcibios_fwaddrmap_lookup(dev); if (!map) { @@ -101,9 +97,6 @@ resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) struct pcibios_fwaddrmap *map; resource_size_t fw_addr = 0; - if (pcibios_fw_addr_done) - return 0; - spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); map = pcibios_fwaddrmap_lookup(dev); if (map) @@ -113,7 +106,7 @@ resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) return fw_addr; } -static void __init pcibios_fw_addr_list_del(void) +static void pcibios_fw_addr_list_del(void) { unsigned long flags; struct pcibios_fwaddrmap *entry, *next; @@ -125,7 +118,6 @@ static void __init pcibios_fw_addr_list_del(void) kfree(entry); } spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); - pcibios_fw_addr_done = true; } static int @@ -201,46 +193,46 @@ EXPORT_SYMBOL(pcibios_align_resource); * as well. */ -static void pcibios_allocate_bridge_resources(struct pci_dev *dev) +static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) { + struct pci_bus *bus; + struct pci_dev *dev; int idx; struct resource *r; - for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { - r = &dev->resource[idx]; - if (!r->flags) - continue; - if (!r->start || pci_claim_resource(dev, idx) < 0) { - /* - * Something is wrong with the region. - * Invalidate the resource to prevent - * child resource allocations in this - * range. - */ - r->start = r->end = 0; - r->flags = 0; + /* Depth-First Search on bus tree */ + list_for_each_entry(bus, bus_list, node) { + if ((dev = bus->self)) { + for (idx = PCI_BRIDGE_RESOURCES; + idx < PCI_NUM_RESOURCES; idx++) { + r = &dev->resource[idx]; + if (!r->flags) + continue; + if (!r->start || + pci_claim_resource(dev, idx) < 0) { + /* + * Something is wrong with the region. + * Invalidate the resource to prevent + * child resource allocations in this + * range. + */ + r->start = r->end = 0; + r->flags = 0; + } + } } + pcibios_allocate_bus_resources(&bus->children); } } -static void pcibios_allocate_bus_resources(struct pci_bus *bus) -{ - struct pci_bus *child; - - /* Depth-First Search on bus tree */ - if (bus->self) - pcibios_allocate_bridge_resources(bus->self); - list_for_each_entry(child, &bus->children, node) - pcibios_allocate_bus_resources(child); -} - struct pci_check_idx_range { int start; int end; }; -static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass) +static void __init pcibios_allocate_resources(int pass) { + struct pci_dev *dev = NULL; int idx, disabled, i; u16 command; struct resource *r; @@ -252,13 +244,14 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass) #endif }; - pci_read_config_word(dev, PCI_COMMAND, &command); - for (i = 0; i < ARRAY_SIZE(idx_range); i++) + for_each_pci_dev(dev) { + pci_read_config_word(dev, PCI_COMMAND, &command); + for (i = 0; i < ARRAY_SIZE(idx_range); i++) for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) { r = &dev->resource[idx]; - if (r->parent) /* Already allocated */ + if (r->parent) /* Already allocated */ continue; - if (!r->start) /* Address not assigned at all */ + if (!r->start) /* Address not assigned at all */ continue; if (r->flags & IORESOURCE_IO) disabled = !(command & PCI_COMMAND_IO); @@ -277,74 +270,44 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass) } } } - if (!pass) { - r = &dev->resource[PCI_ROM_RESOURCE]; - if (r->flags & IORESOURCE_ROM_ENABLE) { - /* Turn the ROM off, leave the resource region, - * but keep it unregistered. */ - u32 reg; - dev_dbg(&dev->dev, "disabling ROM %pR\n", r); - r->flags &= ~IORESOURCE_ROM_ENABLE; - pci_read_config_dword(dev, dev->rom_base_reg, ®); - pci_write_config_dword(dev, dev->rom_base_reg, + if (!pass) { + r = &dev->resource[PCI_ROM_RESOURCE]; + if (r->flags & IORESOURCE_ROM_ENABLE) { + /* Turn the ROM off, leave the resource region, + * but keep it unregistered. */ + u32 reg; + dev_dbg(&dev->dev, "disabling ROM %pR\n", r); + r->flags &= ~IORESOURCE_ROM_ENABLE; + pci_read_config_dword(dev, + dev->rom_base_reg, ®); + pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); + } } } } -static void pcibios_allocate_resources(struct pci_bus *bus, int pass) -{ - struct pci_dev *dev; - struct pci_bus *child; - - list_for_each_entry(dev, &bus->devices, bus_list) { - pcibios_allocate_dev_resources(dev, pass); - - child = dev->subordinate; - if (child) - pcibios_allocate_resources(child, pass); - } -} - -static void pcibios_allocate_dev_rom_resource(struct pci_dev *dev) +static int __init pcibios_assign_resources(void) { + struct pci_dev *dev = NULL; struct resource *r; - /* - * Try to use BIOS settings for ROMs, otherwise let - * pci_assign_unassigned_resources() allocate the new - * addresses. - */ - r = &dev->resource[PCI_ROM_RESOURCE]; - if (!r->flags || !r->start) - return; - - if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) { - r->end -= r->start; - r->start = 0; - } -} -static void pcibios_allocate_rom_resources(struct pci_bus *bus) -{ - struct pci_dev *dev; - struct pci_bus *child; - - list_for_each_entry(dev, &bus->devices, bus_list) { - pcibios_allocate_dev_rom_resource(dev); - - child = dev->subordinate; - if (child) - pcibios_allocate_rom_resources(child); + if (!(pci_probe & PCI_ASSIGN_ROMS)) { + /* + * Try to use BIOS settings for ROMs, otherwise let + * pci_assign_unassigned_resources() allocate the new + * addresses. + */ + for_each_pci_dev(dev) { + r = &dev->resource[PCI_ROM_RESOURCE]; + if (!r->flags || !r->start) + continue; + if (pci_claim_resource(dev, PCI_ROM_RESOURCE) < 0) { + r->end -= r->start; + r->start = 0; + } + } } -} - -static int __init pcibios_assign_resources(void) -{ - struct pci_bus *bus; - - if (!(pci_probe & PCI_ASSIGN_ROMS)) - list_for_each_entry(bus, &pci_root_buses, node) - pcibios_allocate_rom_resources(bus); pci_assign_unassigned_resources(); pcibios_fw_addr_list_del(); @@ -352,32 +315,12 @@ static int __init pcibios_assign_resources(void) return 0; } -void pcibios_resource_survey_bus(struct pci_bus *bus) -{ - dev_printk(KERN_DEBUG, &bus->dev, "Allocating resources\n"); - - pcibios_allocate_bus_resources(bus); - - pcibios_allocate_resources(bus, 0); - pcibios_allocate_resources(bus, 1); - - if (!(pci_probe & PCI_ASSIGN_ROMS)) - pcibios_allocate_rom_resources(bus); -} - void __init pcibios_resource_survey(void) { - struct pci_bus *bus; - DBG("PCI: Allocating resources\n"); - - list_for_each_entry(bus, &pci_root_buses, node) - pcibios_allocate_bus_resources(bus); - - list_for_each_entry(bus, &pci_root_buses, node) - pcibios_allocate_resources(bus, 0); - list_for_each_entry(bus, &pci_root_buses, node) - pcibios_allocate_resources(bus, 1); + pcibios_allocate_bus_resources(&pci_root_buses); + pcibios_allocate_resources(0); + pcibios_allocate_resources(1); e820_reserve_resources_late(); /* diff --git a/trunk/arch/x86/pci/legacy.c b/trunk/arch/x86/pci/legacy.c index a9e83083fb85..a1df191129d3 100644 --- a/trunk/arch/x86/pci/legacy.c +++ b/trunk/arch/x86/pci/legacy.c @@ -30,7 +30,7 @@ int __init pci_legacy_init(void) } printk("PCI: Probing PCI hardware\n"); - pcibios_scan_root(0); + pci_root_bus = pcibios_scan_root(0); return 0; } diff --git a/trunk/arch/x86/pci/numaq_32.c b/trunk/arch/x86/pci/numaq_32.c index 00edfe652b72..83e125b95ca6 100644 --- a/trunk/arch/x86/pci/numaq_32.c +++ b/trunk/arch/x86/pci/numaq_32.c @@ -152,7 +152,7 @@ int __init pci_numaq_init(void) raw_pci_ops = &pci_direct_conf1_mq; - pcibios_scan_root(0); + pci_root_bus = pcibios_scan_root(0); if (num_online_nodes() > 1) for_each_online_node(quad) { if (quad == 0) diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 4ee2e753306a..2a4502becd13 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -37,7 +37,7 @@ acpi-y += resource.o acpi-y += processor_core.o acpi-y += ec.o acpi-$(CONFIG_ACPI_DOCK) += dock.o -acpi-y += pci_root.o pci_link.o pci_irq.o +acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o acpi-y += acpi_platform.o acpi-y += power.o acpi-y += event.o diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 327ab4459558..eb30e5ab4cab 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -157,26 +157,38 @@ static int acpi_memory_get_device(acpi_handle handle, struct acpi_memory_device **mem_device) { + acpi_status status; + acpi_handle phandle; struct acpi_device *device = NULL; + struct acpi_device *pdevice = NULL; int result; + if (!acpi_bus_get_device(handle, &device) && device) goto end; + status = acpi_get_parent(handle, &phandle); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Cannot find acpi parent")); + return -EINVAL; + } + + /* Get the parent device */ + result = acpi_bus_get_device(phandle, &pdevice); + if (result) { + acpi_handle_warn(phandle, "Cannot get acpi bus device\n"); + return -EINVAL; + } + /* * Now add the notified device. This creates the acpi_device * and invokes .add function */ - result = acpi_bus_add(handle); + result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); if (result) { acpi_handle_warn(handle, "Cannot add acpi bus\n"); return -EINVAL; } - result = acpi_bus_get_device(handle, &device); - if (result) { - acpi_handle_warn(handle, "Missing device object\n"); - return -EINVAL; - } end: *mem_device = acpi_driver_data(device); diff --git a/trunk/drivers/acpi/container.c b/trunk/drivers/acpi/container.c index f8fb2281f34a..811910b50b75 100644 --- a/trunk/drivers/acpi/container.c +++ b/trunk/drivers/acpi/container.c @@ -135,6 +135,30 @@ static int acpi_container_remove(struct acpi_device *device, int type) return status; } +static int container_device_add(struct acpi_device **device, acpi_handle handle) +{ + acpi_handle phandle; + struct acpi_device *pdev; + int result; + + + if (acpi_get_parent(handle, &phandle)) { + return -ENODEV; + } + + if (acpi_bus_get_device(phandle, &pdev)) { + return -ENODEV; + } + + if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_DEVICE)) { + return -ENODEV; + } + + result = acpi_bus_start(*device); + + return result; +} + static void container_notify_cb(acpi_handle handle, u32 type, void *context) { struct acpi_device *device = NULL; @@ -166,16 +190,11 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) if (!ACPI_FAILURE(status) || device) break; - result = acpi_bus_add(handle); + result = container_device_add(&device, handle); if (result) { acpi_handle_warn(handle, "Failed to add container\n"); break; } - result = acpi_bus_get_device(handle, &device); - if (result) { - acpi_handle_warn(handle, "Missing device object\n"); - break; - } kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); ost_code = ACPI_OST_SC_SUCCESS; diff --git a/trunk/drivers/acpi/device_pm.c b/trunk/drivers/acpi/device_pm.c index e4f6ac95595c..f09dc987cf17 100644 --- a/trunk/drivers/acpi/device_pm.c +++ b/trunk/drivers/acpi/device_pm.c @@ -353,7 +353,7 @@ int acpi_pm_device_sleep_wake(struct device *dev, bool enable) * acpi_dev_pm_get_node - Get ACPI device node for the given physical device. * @dev: Device to get the ACPI node for. */ -struct acpi_device *acpi_dev_pm_get_node(struct device *dev) +static struct acpi_device *acpi_dev_pm_get_node(struct device *dev) { acpi_handle handle = DEVICE_ACPI_HANDLE(dev); struct acpi_device *adev; diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 9e31b2bd93d3..f32bd47b35e0 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -310,6 +310,8 @@ static int dock_present(struct dock_station *ds) static struct acpi_device * dock_create_acpi_device(acpi_handle handle) { struct acpi_device *device; + struct acpi_device *parent_device; + acpi_handle parent; int ret; if (acpi_bus_get_device(handle, &device)) { @@ -317,11 +319,16 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) * no device created for this object, * so we should create one. */ - ret = acpi_bus_add(handle); - if (ret) - pr_debug("error adding bus, %x\n", -ret); + acpi_get_parent(handle, &parent); + if (acpi_bus_get_device(parent, &parent_device)) + parent_device = NULL; - acpi_bus_get_device(handle, &device); + ret = acpi_bus_add(&device, parent_device, handle, + ACPI_BUS_TYPE_DEVICE); + if (ret) { + pr_debug("error adding bus, %x\n", -ret); + return NULL; + } } return device; } diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index ac00b882e75d..01551840d236 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -63,9 +63,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(&bus_type_sem); list_for_each_entry(tmp, &bus_type_list, list) { if (tmp->bus == type) { @@ -267,39 +264,28 @@ static int acpi_platform_notify(struct device *dev) { struct acpi_bus_type *type; acpi_handle handle; - int ret; + int ret = -EINVAL; ret = acpi_bind_one(dev, NULL); - if (ret && (!dev->bus || !dev->parent)) { + if (!ret) + goto out; + + if (!dev->bus || !dev->parent) { /* bridge devices genernally haven't bus or parent */ ret = acpi_find_bridge_device(dev, &handle); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } + goto end; } - type = acpi_get_bus_type(dev->bus); - if (ret) { - if (!type || !type->find_device) { - DBG("No ACPI bus support for %s\n", dev_name(dev)); - ret = -EINVAL; - goto out; - } - - ret = type->find_device(dev, &handle); - if (ret) { - DBG("Unable to get handle for %s\n", dev_name(dev)); - goto out; - } - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; + if (!type) { + DBG("No ACPI bus support for %s\n", dev_name(dev)); + ret = -EINVAL; + goto end; } - - if (type && type->setup) - type->setup(dev); + if ((ret = type->find_device(dev, &handle)) != 0) + DBG("Can't get handler for %s\n", dev_name(dev)); + end: + if (!ret) + acpi_bind_one(dev, handle); out: #if ACPI_GLUE_DEBUG @@ -318,12 +304,6 @@ static int acpi_platform_notify(struct device *dev) static int acpi_platform_notify_remove(struct device *dev) { - struct acpi_bus_type *type; - - type = acpi_get_bus_type(dev->bus); - if (type && type->cleanup) - type->cleanup(dev); - acpi_unbind_one(dev); return 0; } diff --git a/trunk/drivers/acpi/internal.h b/trunk/drivers/acpi/internal.h index e050254ae143..3c407cdc1ec1 100644 --- a/trunk/drivers/acpi/internal.h +++ b/trunk/drivers/acpi/internal.h @@ -67,7 +67,6 @@ struct acpi_ec { extern struct acpi_ec *first_ec; -int acpi_pci_root_init(void); int acpi_ec_init(void); int acpi_ec_ecdt_probe(void); int acpi_boot_ec_enable(void); diff --git a/trunk/drivers/acpi/pci_bind.c b/trunk/drivers/acpi/pci_bind.c new file mode 100644 index 000000000000..a1dee29beed3 --- /dev/null +++ b/trunk/drivers/acpi/pci_bind.c @@ -0,0 +1,122 @@ +/* + * pci_bind.c - ACPI PCI Device Binding ($Revision: 2 $) + * + * Copyright (C) 2001, 2002 Andy Grover + * Copyright (C) 2001, 2002 Paul Diefenbaugh + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define _COMPONENT ACPI_PCI_COMPONENT +ACPI_MODULE_NAME("pci_bind"); + +static int acpi_pci_unbind(struct acpi_device *device) +{ + struct pci_dev *dev; + + dev = acpi_get_pci_dev(device->handle); + if (!dev) + goto out; + + device_set_run_wake(&dev->dev, false); + pci_acpi_remove_pm_notifier(device); + acpi_power_resource_unregister_device(&dev->dev, device->handle); + + if (!dev->subordinate) + goto out; + + acpi_pci_irq_del_prt(pci_domain_nr(dev->bus), dev->subordinate->number); + + device->ops.bind = NULL; + device->ops.unbind = NULL; + +out: + pci_dev_put(dev); + return 0; +} + +static int acpi_pci_bind(struct acpi_device *device) +{ + acpi_status status; + acpi_handle handle; + unsigned char bus; + struct pci_dev *dev; + + dev = acpi_get_pci_dev(device->handle); + if (!dev) + return 0; + + pci_acpi_add_pm_notifier(device, dev); + acpi_power_resource_register_device(&dev->dev, device->handle); + if (device->wakeup.flags.run_wake) + device_set_run_wake(&dev->dev, true); + + /* + * Install the 'bind' function to facilitate callbacks for + * children of the P2P bridge. + */ + if (dev->subordinate) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Device %04x:%02x:%02x.%d is a PCI bridge\n", + pci_domain_nr(dev->bus), dev->bus->number, + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn))); + device->ops.bind = acpi_pci_bind; + device->ops.unbind = acpi_pci_unbind; + } + + /* + * Evaluate and parse _PRT, if exists. This code allows parsing of + * _PRT objects within the scope of non-bridge devices. Note that + * _PRTs within the scope of a PCI bridge assume the bridge's + * subordinate bus number. + * + * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? + */ + status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); + if (ACPI_FAILURE(status)) + goto out; + + if (dev->subordinate) + bus = dev->subordinate->number; + else + bus = dev->bus->number; + + acpi_pci_irq_add_prt(device->handle, pci_domain_nr(dev->bus), bus); + +out: + pci_dev_put(dev); + return 0; +} + +int acpi_pci_bind_root(struct acpi_device *device) +{ + device->ops.bind = acpi_pci_bind; + device->ops.unbind = acpi_pci_unbind; + + return 0; +} diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index bf5108ad4d63..7928d4dc7056 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -47,6 +47,7 @@ ACPI_MODULE_NAME("pci_root"); #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" static int acpi_pci_root_add(struct acpi_device *device); static int acpi_pci_root_remove(struct acpi_device *device, int type); +static int acpi_pci_root_start(struct acpi_device *device); #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | OSC_ACTIVE_STATE_PWR_SUPPORT \ @@ -66,6 +67,7 @@ static struct acpi_driver acpi_pci_root_driver = { .ops = { .add = acpi_pci_root_add, .remove = acpi_pci_root_remove, + .start = acpi_pci_root_start, }, }; @@ -107,6 +109,24 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) } EXPORT_SYMBOL(acpi_pci_unregister_driver); +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) +{ + struct acpi_pci_root *root; + acpi_handle handle = NULL; + + mutex_lock(&acpi_pci_root_lock); + list_for_each_entry(root, &acpi_pci_roots, node) + if ((root->segment == (u16) seg) && + (root->secondary.start == (u16) bus)) { + handle = root->device->handle; + break; + } + mutex_unlock(&acpi_pci_root_lock); + return handle; +} + +EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); + /** * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge * @handle - the ACPI CA node in question. @@ -168,6 +188,21 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, return AE_OK; } +static void acpi_pci_bridge_scan(struct acpi_device *device) +{ + int status; + struct acpi_device *child = NULL; + + if (device->flags.bus_address) + if (device->parent && device->parent->ops.bind) { + status = device->parent->ops.bind(device); + if (!status) { + list_for_each_entry(child, &device->children, node) + acpi_pci_bridge_scan(child); + } + } +} + static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; static acpi_status acpi_pci_run_osc(acpi_handle handle, @@ -417,7 +452,7 @@ static int acpi_pci_root_add(struct acpi_device *device) int result; struct acpi_pci_root *root; acpi_handle handle; - struct acpi_pci_driver *driver; + struct acpi_device *child; u32 flags, base_flags; bool is_osc_granted = false; @@ -568,6 +603,21 @@ static int acpi_pci_root_add(struct acpi_device *device) goto out_del_root; } + /* + * Attach ACPI-PCI Context + * ----------------------- + * Thus binding the ACPI and PCI devices. + */ + result = acpi_pci_bind_root(device); + if (result) + goto out_del_root; + + /* + * Scan and bind all _ADR-Based Devices + */ + list_for_each_entry(child, &device->children, node) + acpi_pci_bridge_scan(child); + /* ASPM setting */ if (is_osc_granted) { if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) @@ -582,10 +632,26 @@ static int acpi_pci_root_add(struct acpi_device *device) if (device->wakeup.flags.run_wake) device_set_run_wake(root->bus->bridge, true); - if (system_state != SYSTEM_BOOTING) { - pcibios_resource_survey_bus(root->bus); + return 0; + +out_del_root: + mutex_lock(&acpi_pci_root_lock); + list_del(&root->node); + mutex_unlock(&acpi_pci_root_lock); + + acpi_pci_irq_del_prt(root->segment, root->secondary.start); +end: + kfree(root); + return result; +} + +static int acpi_pci_root_start(struct acpi_device *device) +{ + struct acpi_pci_root *root = acpi_driver_data(device); + struct acpi_pci_driver *driver; + + if (system_state != SYSTEM_BOOTING) pci_assign_unassigned_bus_resources(root->bus); - } mutex_lock(&acpi_pci_root_lock); list_for_each_entry(driver, &acpi_pci_drivers, node) @@ -598,17 +664,8 @@ static int acpi_pci_root_add(struct acpi_device *device) pci_enable_bridges(root->bus); pci_bus_add_devices(root->bus); - return 0; - -out_del_root: - mutex_lock(&acpi_pci_root_lock); - list_del(&root->node); - mutex_unlock(&acpi_pci_root_lock); - acpi_pci_irq_del_prt(root->segment, root->secondary.start); -end: - kfree(root); - return result; + return 0; } static int acpi_pci_root_remove(struct acpi_device *device, int type) @@ -642,7 +699,7 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) return 0; } -int __init acpi_pci_root_init(void) +static int __init acpi_pci_root_init(void) { acpi_hest_init(); @@ -655,3 +712,5 @@ int __init acpi_pci_root_init(void) return 0; } + +subsys_initcall(acpi_pci_root_init); diff --git a/trunk/drivers/acpi/processor_driver.c b/trunk/drivers/acpi/processor_driver.c index 0777663f443e..e83311bf1ebd 100644 --- a/trunk/drivers/acpi/processor_driver.c +++ b/trunk/drivers/acpi/processor_driver.c @@ -677,6 +677,28 @@ static int is_processor_present(acpi_handle handle) return 0; } +static +int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) +{ + acpi_handle phandle; + struct acpi_device *pdev; + + + if (acpi_get_parent(handle, &phandle)) { + return -ENODEV; + } + + if (acpi_bus_get_device(phandle, &pdev)) { + return -ENODEV; + } + + if (acpi_bus_add(device, pdev, handle, ACPI_BUS_TYPE_PROCESSOR)) { + return -ENODEV; + } + + return 0; +} + static void acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) { @@ -699,16 +721,12 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, if (!acpi_bus_get_device(handle, &device)) break; - result = acpi_bus_add(handle); + result = acpi_processor_device_add(handle, &device); if (result) { acpi_handle_err(handle, "Unable to add the device\n"); break; } - result = acpi_bus_get_device(handle, &device); - if (result) { - acpi_handle_err(handle, "Missing device object\n"); - break; - } + ost_code = ACPI_OST_SC_SUCCESS; break; diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index e380345b643a..53502d1bbf26 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -494,8 +494,7 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv) struct acpi_device *acpi_dev = to_acpi_device(dev); struct acpi_driver *acpi_drv = to_acpi_driver(drv); - return acpi_dev->flags.match_driver - && !acpi_match_device_ids(acpi_dev, acpi_drv->ids); + return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); } static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env) @@ -571,6 +570,7 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) } static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *); +static int acpi_start_single_object(struct acpi_device *); static int acpi_device_probe(struct device * dev) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -579,6 +579,9 @@ static int acpi_device_probe(struct device * dev) ret = acpi_bus_driver_init(acpi_dev, acpi_drv); if (!ret) { + if (acpi_dev->bus_ops.acpi_op_start) + acpi_start_single_object(acpi_dev); + if (acpi_drv->ops.notify) { ret = acpi_device_install_notify_handler(acpi_dev); if (ret) { @@ -757,6 +760,24 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) return 0; } +static int acpi_start_single_object(struct acpi_device *device) +{ + int result = 0; + struct acpi_driver *driver; + + + if (!(driver = device->driver)) + return 0; + + if (driver->ops.start) { + result = driver->ops.start(device); + if (result && driver->ops.remove) + driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); + } + + return result; +} + /** * acpi_bus_register_driver - register a driver with the ACPI bus * @driver: driver being registered @@ -1385,6 +1406,13 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) if (!rmdevice) return 0; + /* + * unbind _ADR-Based Devices when hot removal + */ + if (dev->flags.bus_address) { + if ((dev->parent) && (dev->parent->ops.unbind)) + dev->parent->ops.unbind(dev); + } acpi_device_unregister(dev, ACPI_BUS_REMOVAL_EJECT); return 0; @@ -1392,7 +1420,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) static int acpi_add_single_object(struct acpi_device **child, acpi_handle handle, int type, - unsigned long long sta, bool match_driver) + unsigned long long sta, + struct acpi_bus_ops *ops) { int result; struct acpi_device *device; @@ -1408,6 +1437,7 @@ static int acpi_add_single_object(struct acpi_device **child, device->device_type = type; device->handle = handle; device->parent = acpi_bus_get_parent(handle); + device->bus_ops = *ops; /* workround for not call .start */ STRUCT_TO_INT(device->status) = sta; acpi_device_get_busid(device); @@ -1458,9 +1488,16 @@ static int acpi_add_single_object(struct acpi_device **child, if ((result = acpi_device_set_context(device))) goto end; - device->flags.match_driver = match_driver; result = acpi_device_register(device); + /* + * Bind _ADR-Based Devices when hot add + */ + if (device->flags.bus_address) { + if (device->parent && device->parent->ops.bind) + device->parent->ops.bind(device); + } + end: if (!result) { acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -1482,12 +1519,16 @@ static int acpi_add_single_object(struct acpi_device **child, static void acpi_bus_add_power_resource(acpi_handle handle) { + struct acpi_bus_ops ops = { + .acpi_op_add = 1, + .acpi_op_start = 1, + }; struct acpi_device *device = NULL; acpi_bus_get_device(handle, &device); if (!device) acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, - ACPI_STA_DEFAULT, true); + ACPI_STA_DEFAULT, &ops); } static int acpi_bus_type_and_status(acpi_handle handle, int *type, @@ -1529,19 +1570,16 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type, return 0; } -static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, - void *not_used, void **return_value) +static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, + void *context, void **return_value) { - struct acpi_device *device = NULL; + struct acpi_bus_ops *ops = context; int type; unsigned long long sta; + struct acpi_device *device; acpi_status status; int result; - acpi_bus_get_device(handle, &device); - if (device) - goto out; - result = acpi_bus_type_and_status(handle, &type, &sta); if (result) return AE_OK; @@ -1558,90 +1596,98 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, return AE_CTRL_DEPTH; } - acpi_add_single_object(&device, handle, type, sta, - type == ACPI_BUS_TYPE_POWER); + /* + * We may already have an acpi_device from a previous enumeration. If + * so, we needn't add it again, but we may still have to start it. + */ + device = NULL; + acpi_bus_get_device(handle, &device); + if (ops->acpi_op_add && !device) { + acpi_add_single_object(&device, handle, type, sta, ops); + /* Is the device a known good platform device? */ + if (device + && !acpi_match_device_ids(device, acpi_platform_device_ids)) + acpi_create_platform_device(device); + } + if (!device) return AE_CTRL_DEPTH; - device->flags.match_driver = true; + if (ops->acpi_op_start && !(ops->acpi_op_add)) { + status = acpi_start_single_object(device); + if (ACPI_FAILURE(status)) + return AE_CTRL_DEPTH; + } - out: if (!*return_value) *return_value = device; - return AE_OK; } -static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, - void *not_used, void **ret_not_used) -{ - acpi_status status = AE_OK; - struct acpi_device *device; - unsigned long long sta_not_used; - int type_not_used; - - /* - * Ignore errors ignored by acpi_bus_check_add() to avoid terminating - * namespace walks prematurely. - */ - if (acpi_bus_type_and_status(handle, &type_not_used, &sta_not_used)) - return AE_OK; - - if (acpi_bus_get_device(handle, &device)) - return AE_CTRL_DEPTH; - - if (!acpi_match_device_ids(device, acpi_platform_device_ids)) { - /* This is a known good platform device. */ - acpi_create_platform_device(device); - } else if (device_attach(&device->dev)) { - status = AE_CTRL_DEPTH; - } - return status; -} - -static int acpi_bus_scan(acpi_handle handle) +static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops, + struct acpi_device **child) { + acpi_status status; void *device = NULL; - if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) + status = acpi_bus_check_add(handle, 0, ops, &device); + if (ACPI_SUCCESS(status)) acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, - acpi_bus_check_add, NULL, NULL, &device); + acpi_bus_check_add, NULL, ops, &device); - if (!device) - return -ENODEV; - - if (ACPI_SUCCESS(acpi_bus_device_attach(handle, 0, NULL, NULL))) - acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, - acpi_bus_device_attach, NULL, NULL, NULL); + if (child) + *child = device; - return 0; + if (device) + return 0; + else + return -ENODEV; } -/** - * acpi_bus_add - Add ACPI device node objects in a given namespace scope. - * @handle: Root of the namespace scope to scan. +/* + * acpi_bus_add and acpi_bus_start * - * Scan a given ACPI tree (probably recently hot-plugged) and create and add - * found devices. + * scan a given ACPI tree and (probably recently hot-plugged) + * create and add or starts found devices. * - * If no devices were found, -ENODEV is returned, but it does not mean that - * there has been a real error. There just have been no suitable ACPI objects - * in the table trunk from which the kernel could create a device and add an - * appropriate driver. + * If no devices were found -ENODEV is returned which does not + * mean that this is a real error, there just have been no suitable + * ACPI objects in the table trunk from which the kernel could create + * a device and add/start an appropriate driver. */ -int acpi_bus_add(acpi_handle handle) + +int +acpi_bus_add(struct acpi_device **child, + struct acpi_device *parent, acpi_handle handle, int type) { - int err; + struct acpi_bus_ops ops; - err = acpi_bus_scan(handle); - if (err) - return err; + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; - acpi_update_all_gpes(); - return 0; + return acpi_bus_scan(handle, &ops, child); } EXPORT_SYMBOL(acpi_bus_add); +int acpi_bus_start(struct acpi_device *device) +{ + struct acpi_bus_ops ops; + int result; + + if (!device) + return -EINVAL; + + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_start = 1; + + result = acpi_bus_scan(device->handle, &ops, NULL); + + acpi_update_all_gpes(); + + return result; +} +EXPORT_SYMBOL(acpi_bus_start); + int acpi_bus_trim(struct acpi_device *start, int rmdevice) { acpi_status status; @@ -1701,6 +1747,11 @@ static int acpi_bus_scan_fixed(void) { int result = 0; struct acpi_device *device = NULL; + struct acpi_bus_ops ops; + + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; /* * Enumerate all fixed-feature devices. @@ -1708,14 +1759,16 @@ static int acpi_bus_scan_fixed(void) if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { result = acpi_add_single_object(&device, NULL, ACPI_BUS_TYPE_POWER_BUTTON, - ACPI_STA_DEFAULT, true); + ACPI_STA_DEFAULT, + &ops); device_init_wakeup(&device->dev, true); } if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { result = acpi_add_single_object(&device, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON, - ACPI_STA_DEFAULT, true); + ACPI_STA_DEFAULT, + &ops); } return result; @@ -1724,6 +1777,11 @@ static int acpi_bus_scan_fixed(void) int __init acpi_scan_init(void) { int result; + struct acpi_bus_ops ops; + + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; result = bus_register(&acpi_bus_type); if (result) { @@ -1732,16 +1790,12 @@ int __init acpi_scan_init(void) } acpi_power_init(); - acpi_pci_root_init(); /* * Enumerate devices in the ACPI namespace. */ - result = acpi_bus_scan(ACPI_ROOT_OBJECT); - if (result) - return result; + result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root); - result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); if (!result) result = acpi_bus_scan_fixed(); diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 847f3ca47bb8..ad6a8b635692 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -158,8 +158,6 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, return ret; } -void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } - /** * pci_bus_add_device - add a single device * @dev: device to add diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 91b5ad875c53..3d6d4fd1e3c5 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -734,9 +734,15 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus) */ static int acpiphp_bus_add(struct acpiphp_func *func) { - struct acpi_device *device; + acpi_handle phandle; + struct acpi_device *device, *pdevice; int ret_val; + acpi_get_parent(func->handle, &phandle); + if (acpi_bus_get_device(phandle, &pdevice)) { + dbg("no parent device, assuming NULL\n"); + pdevice = NULL; + } if (!acpi_bus_get_device(func->handle, &device)) { dbg("bus exists... trim\n"); /* this shouldn't be in here, so remove @@ -746,13 +752,16 @@ static int acpiphp_bus_add(struct acpiphp_func *func) dbg("acpi_bus_trim return %x\n", ret_val); } - ret_val = acpi_bus_add(func->handle); - if (!ret_val) - ret_val = acpi_bus_get_device(func->handle, &device); - - if (ret_val) - dbg("error adding bus, %x\n", -ret_val); + ret_val = acpi_bus_add(&device, pdevice, func->handle, + ACPI_BUS_TYPE_DEVICE); + if (ret_val) { + dbg("error adding bus, %x\n", + -ret_val); + goto acpiphp_bus_add_out; + } + ret_val = acpi_bus_start(device); +acpiphp_bus_add_out: return ret_val; } @@ -1121,7 +1130,8 @@ static int acpiphp_configure_bridge (acpi_handle handle) static void handle_bridge_insertion(acpi_handle handle, u32 type) { - struct acpi_device *device; + struct acpi_device *device, *pdevice; + acpi_handle phandle; if ((type != ACPI_NOTIFY_BUS_CHECK) && (type != ACPI_NOTIFY_DEVICE_CHECK)) { @@ -1129,15 +1139,17 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) return; } - if (acpi_bus_add(handle)) { - err("cannot add bridge to acpi list\n"); - return; + acpi_get_parent(handle, &phandle); + if (acpi_bus_get_device(phandle, &pdevice)) { + dbg("no parent device, assuming NULL\n"); + pdevice = NULL; } - if (acpi_bus_get_device(handle, &device)) { - err("ACPI device object missing\n"); + if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) { + err("cannot add bridge to acpi list\n"); return; } - if (!acpiphp_configure_bridge(handle)) + if (!acpiphp_configure_bridge(handle) && + !acpi_bus_start(device)) add_bridge(handle); else err("cannot configure and start bridge\n"); diff --git a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c index d282019cda5f..36112fe212d3 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1900,7 +1900,8 @@ static void interrupt_event_handler(struct controller *ctrl) dbg("power fault\n"); } else { /* refresh notification */ - update_slot_info(ctrl, p_slot); + if (p_slot) + update_slot_info(ctrl, p_slot); } ctrl->event_queue[loop].event_type = 0; @@ -2519,28 +2520,44 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func /* If we have IO resources copy them and fill in the bridge's * IO range registers */ - memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); - io_node->next = NULL; + if (io_node) { + memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); + io_node->next = NULL; - /* set IO base and Limit registers */ - temp_byte = io_node->base >> 8; - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); + /* set IO base and Limit registers */ + temp_byte = io_node->base >> 8; + rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); - temp_byte = (io_node->base + io_node->length - 1) >> 8; - rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); + temp_byte = (io_node->base + io_node->length - 1) >> 8; + rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); + } else { + kfree(hold_IO_node); + hold_IO_node = NULL; + } - /* Copy the memory resources and fill in the bridge's memory - * range registers. - */ - memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); - mem_node->next = NULL; + /* If we have memory resources copy them and fill in the + * bridge's memory range registers. Otherwise, fill in the + * range registers with values that disable them. */ + if (mem_node) { + memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); + mem_node->next = NULL; - /* set Mem base and Limit registers */ - temp_word = mem_node->base >> 16; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); + /* set Mem base and Limit registers */ + temp_word = mem_node->base >> 16; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); - temp_word = (mem_node->base + mem_node->length - 1) >> 16; - rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); + temp_word = (mem_node->base + mem_node->length - 1) >> 16; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); + } else { + temp_word = 0xFFFF; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); + + temp_word = 0x0000; + rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); + + kfree(hold_mem_node); + hold_mem_node = NULL; + } memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); p_mem_node->next = NULL; @@ -2610,7 +2627,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func /* Return unused bus resources * First use the temporary node to store information for * the board */ - if (bus_node && temp_resources.bus_head) { + if (hold_bus_node && bus_node && temp_resources.bus_head) { hold_bus_node->length = bus_node->base - hold_bus_node->base; hold_bus_node->next = func->bus_head; @@ -2734,7 +2751,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func } /* If we have prefetchable memory space available and there * is some left at the end, return the unused portion */ - if (temp_resources.p_mem_head) { + if (hold_p_mem_node && temp_resources.p_mem_head) { p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), &hold_p_mem_node, 0x100000); diff --git a/trunk/drivers/pci/hotplug/sgi_hotplug.c b/trunk/drivers/pci/hotplug/sgi_hotplug.c index f3c419256d2a..f64ca92253da 100644 --- a/trunk/drivers/pci/hotplug/sgi_hotplug.c +++ b/trunk/drivers/pci/hotplug/sgi_hotplug.c @@ -412,6 +412,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (SN_ACPI_BASE_SUPPORT() && ssdt) { unsigned long long adr; struct acpi_device *pdevice; + struct acpi_device *device; acpi_handle phandle; acpi_handle chandle = NULL; acpi_handle rethandle; @@ -447,7 +448,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) if (ACPI_SUCCESS(ret) && (adr>>16) == (slot->device_num + 1)) { - ret = acpi_bus_add(chandle); + ret = acpi_bus_add(&device, pdevice, chandle, + ACPI_BUS_TYPE_DEVICE); if (ACPI_FAILURE(ret)) { printk(KERN_ERR "%s: acpi_bus_add " "failed (0x%x) for slot %d " @@ -455,6 +457,8 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) ret, (int)(adr>>16), (int)(adr&0xffff)); /* try to continue on */ + } else { + acpi_bus_start(device); } } } diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index 1c2587c40299..1af4008182fd 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -283,6 +283,7 @@ static struct pci_platform_pm_ops acpi_pci_platform_pm = { .is_manageable = acpi_pci_power_manageable, .set_state = acpi_pci_set_power_state, .choose_state = acpi_pci_choose_state, + .can_wakeup = acpi_pci_can_wakeup, .sleep_wake = acpi_pci_sleep_wake, .run_wake = acpi_pci_run_wake, }; @@ -302,66 +303,28 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) return 0; } -static void pci_acpi_setup(struct device *dev) +static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) { - struct pci_dev *pci_dev = to_pci_dev(dev); - acpi_handle handle = ACPI_HANDLE(dev); - struct acpi_device *adev; - acpi_status status; - acpi_handle dummy; + int num; + unsigned int seg, bus; /* - * Evaluate and parse _PRT, if exists. This code allows parsing of - * _PRT objects within the scope of non-bridge devices. Note that - * _PRTs within the scope of a PCI bridge assume the bridge's - * subordinate bus number. - * - * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? + * The string should be the same as root bridge's name + * Please look at 'pci_scan_bus_parented' */ - status = acpi_get_handle(handle, METHOD_NAME__PRT, &dummy); - if (ACPI_SUCCESS(status)) { - unsigned char bus; - - bus = pci_dev->subordinate ? - pci_dev->subordinate->number : pci_dev->bus->number; - acpi_pci_irq_add_prt(handle, pci_domain_nr(pci_dev->bus), bus); - } - - acpi_power_resource_register_device(dev, handle); - if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) - return; - - device_set_wakeup_capable(dev, true); - acpi_pci_sleep_wake(pci_dev, false); - - pci_acpi_add_pm_notifier(adev, pci_dev); - if (adev->wakeup.flags.run_wake) - device_set_run_wake(dev, true); -} - -static void pci_acpi_cleanup(struct device *dev) -{ - struct pci_dev *pci_dev = to_pci_dev(dev); - acpi_handle handle = ACPI_HANDLE(dev); - struct acpi_device *adev; - - if (!acpi_bus_get_device(handle, &adev) && adev->wakeup.flags.valid) { - device_set_wakeup_capable(dev, false); - device_set_run_wake(dev, false); - pci_acpi_remove_pm_notifier(adev); - } - acpi_power_resource_unregister_device(dev, handle); - - if (pci_dev->subordinate) - acpi_pci_irq_del_prt(pci_domain_nr(pci_dev->bus), - pci_dev->subordinate->number); + num = sscanf(dev_name(dev), "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 acpi_pci_bus = { .bus = &pci_bus_type, .find_device = acpi_pci_find_device, - .setup = pci_acpi_setup, - .cleanup = pci_acpi_cleanup, + .find_bridge = acpi_pci_find_root_bridge, }; static int __init acpi_pci_init(void) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 89dc8ac096ba..8b47f70b7d8f 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -450,7 +450,7 @@ static struct pci_platform_pm_ops *pci_platform_pm; int pci_set_platform_pm(struct pci_platform_pm_ops *ops) { if (!ops->is_manageable || !ops->set_state || !ops->choose_state - || !ops->sleep_wake) + || !ops->sleep_wake || !ops->can_wakeup) return -EINVAL; pci_platform_pm = ops; return 0; @@ -473,6 +473,11 @@ static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev) pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR; } +static inline bool platform_pci_can_wakeup(struct pci_dev *dev) +{ + return pci_platform_pm ? pci_platform_pm->can_wakeup(dev) : false; +} + static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable) { return pci_platform_pm ? @@ -1151,7 +1156,8 @@ int pci_reenable_device(struct pci_dev *dev) return 0; } -static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) +static int __pci_enable_device_flags(struct pci_dev *dev, + resource_size_t flags) { int err; int i, bars = 0; @@ -1195,7 +1201,7 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) */ int pci_enable_device_io(struct pci_dev *dev) { - return pci_enable_device_flags(dev, IORESOURCE_IO); + return __pci_enable_device_flags(dev, IORESOURCE_IO); } /** @@ -1208,7 +1214,7 @@ int pci_enable_device_io(struct pci_dev *dev) */ int pci_enable_device_mem(struct pci_dev *dev) { - return pci_enable_device_flags(dev, IORESOURCE_MEM); + return __pci_enable_device_flags(dev, IORESOURCE_MEM); } /** @@ -1224,7 +1230,7 @@ int pci_enable_device_mem(struct pci_dev *dev) */ int pci_enable_device(struct pci_dev *dev) { - return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); + return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } /* @@ -1979,6 +1985,25 @@ void pci_pm_init(struct pci_dev *dev) } } +/** + * platform_pci_wakeup_init - init platform wakeup if present + * @dev: PCI device + * + * Some devices don't have PCI PM caps but can still generate wakeup + * events through platform methods (like ACPI events). If @dev supports + * platform wakeup events, set the device flag to indicate as much. This + * may be redundant if the device also supports PCI PM caps, but double + * initialization should be safe in that case. + */ +void platform_pci_wakeup_init(struct pci_dev *dev) +{ + if (!platform_pci_can_wakeup(dev)) + return; + + device_set_wakeup_capable(&dev->dev, true); + platform_pci_sleep_wake(dev, false); +} + static void pci_add_saved_cap(struct pci_dev *pci_dev, struct pci_cap_saved_state *new_cap) { @@ -2044,6 +2069,9 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) /** * pci_enable_ari - enable ARI forwarding if hardware support it * @dev: the PCI device + * + * If @dev and its upstream bridge both support ARI, enable ARI in the + * bridge. Otherwise, disable ARI in the bridge. */ void pci_enable_ari(struct pci_dev *dev) { @@ -2053,9 +2081,6 @@ void pci_enable_ari(struct pci_dev *dev) if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) return; - if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) - return; - bridge = dev->bus->self; if (!bridge) return; @@ -2064,8 +2089,15 @@ void pci_enable_ari(struct pci_dev *dev) if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; - pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); - bridge->ari_enabled = 1; + if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { + pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 1; + } else { + pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ARI); + bridge->ari_enabled = 0; + } } /** diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index adfd172c5b9b..e8518292826f 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -43,6 +43,9 @@ int pci_probe_reset_function(struct pci_dev *dev); * platform; to be used during system-wide transitions from a * sleeping state to the working state and vice versa * + * @can_wakeup: returns 'true' if given device is capable of waking up the + * system from a sleeping state + * * @sleep_wake: enables/disables the system wake up capability of given device * * @run_wake: enables/disables the platform to generate run-time wake-up events @@ -56,6 +59,7 @@ struct pci_platform_pm_ops { bool (*is_manageable)(struct pci_dev *dev); int (*set_state)(struct pci_dev *dev, pci_power_t state); pci_power_t (*choose_state)(struct pci_dev *dev); + bool (*can_wakeup)(struct pci_dev *dev); int (*sleep_wake)(struct pci_dev *dev, bool enable); int (*run_wake)(struct pci_dev *dev, bool enable); }; @@ -70,6 +74,7 @@ extern void pci_wakeup_bus(struct pci_bus *bus); extern void pci_config_pm_runtime_get(struct pci_dev *dev); extern void pci_config_pm_runtime_put(struct pci_dev *dev); extern void pci_pm_init(struct pci_dev *dev); +extern void platform_pci_wakeup_init(struct pci_dev *dev); extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); void pci_free_cap_save_buffers(struct pci_dev *dev); diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index bbe4be7fc685..6186f03d84f3 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -1280,6 +1280,7 @@ static void pci_init_capabilities(struct pci_dev *dev) /* Power Management */ pci_pm_init(dev); + platform_pci_wakeup_init(dev); /* Vital Product Data */ pci_vpd_pci22_init(dev); @@ -1632,18 +1633,6 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) return max; } -/** - * pcibios_root_bridge_prepare - Platform-specific host bridge setup. - * @bridge: Host bridge to set up. - * - * Default empty implementation. Replace with an architecture-specific setup - * routine, if necessary. - */ -int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) -{ - return 0; -} - struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources) { @@ -1677,10 +1666,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, bridge->dev.parent = parent; bridge->dev.release = pci_release_bus_bridge_dev; dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); - error = pcibios_root_bridge_prepare(bridge); - if (error) - goto bridge_dev_reg_err; - error = device_register(&bridge->dev); if (error) goto bridge_dev_reg_err; diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 796ccc3247df..7ced5dc20dd3 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -95,10 +95,17 @@ typedef int (*acpi_op_bind) (struct acpi_device * device); typedef int (*acpi_op_unbind) (struct acpi_device * device); typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); +struct acpi_bus_ops { + u32 acpi_op_add:1; + u32 acpi_op_start:1; +}; + struct acpi_device_ops { acpi_op_add add; acpi_op_remove remove; acpi_op_start start; + acpi_op_bind bind; + acpi_op_unbind unbind; acpi_op_notify notify; }; @@ -141,8 +148,7 @@ struct acpi_device_flags { u32 power_manageable:1; u32 performance_manageable:1; u32 eject_pending:1; - u32 match_driver:1; - u32 reserved:23; + u32 reserved:24; }; /* File System */ @@ -277,6 +283,7 @@ struct acpi_device { struct acpi_driver *driver; void *driver_data; struct device dev; + struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ u8 physical_node_count; struct list_head physical_node_list; @@ -349,9 +356,11 @@ static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 ty #endif int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); -int acpi_bus_add(acpi_handle handle); +int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, + acpi_handle handle, int type); void acpi_bus_hot_remove_device(void *context); int acpi_bus_trim(struct acpi_device *start, int rmdevice); +int acpi_bus_start(struct acpi_device *device); acpi_status acpi_bus_get_ejd(acpi_handle handle, acpi_handle * ejd); int acpi_match_device_ids(struct acpi_device *device, const struct acpi_device_id *ids); @@ -381,8 +390,6 @@ struct acpi_bus_type { int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ int (*find_bridge) (struct device *, acpi_handle *); - void (*setup)(struct device *); - void (*cleanup)(struct device *); }; int register_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *); @@ -390,6 +397,7 @@ int unregister_acpi_bus_type(struct acpi_bus_type *); struct acpi_pci_root { struct list_head node; struct acpi_device * device; + struct acpi_pci_id id; struct pci_bus *bus; u16 segment; struct resource secondary; /* downstream bus range */ @@ -402,6 +410,7 @@ struct acpi_pci_root { /* helper */ acpi_handle acpi_get_child(acpi_handle, u64); int acpi_is_root_bridge(acpi_handle); +acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 8c1d6f2a2193..3994d7790b23 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -526,14 +526,9 @@ static inline int acpi_subsys_resume_early(struct device *dev) { return 0; } #endif #if defined(CONFIG_ACPI) && defined(CONFIG_PM) -struct acpi_device *acpi_dev_pm_get_node(struct device *dev); int acpi_dev_pm_attach(struct device *dev, bool power_on); void acpi_dev_pm_detach(struct device *dev, bool power_off); #else -static inline struct acpi_device *acpi_dev_pm_get_node(struct device *dev) -{ - return NULL; -} static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) { return -ENODEV; diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 6860f4dec997..15472d691ee6 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -378,8 +378,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, void (*release_fn)(struct pci_host_bridge *), void *release_data); -int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge); - /* * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond * to P2P or CardBus bridge windows) go in a table. Additional ones (for @@ -676,7 +674,6 @@ extern struct list_head pci_root_buses; /* list of all known PCI buses */ /* Some device drivers need know if pci is initiated */ extern int no_pci_devices(void); -void pcibios_resource_survey_bus(struct pci_bus *bus); void pcibios_fixup_bus(struct pci_bus *); int __must_check pcibios_enable_device(struct pci_dev *, int mask); /* Architecture specific versions may override this (weak) */