diff options
| -rw-r--r-- | drivers/acpi/internal.h | 1 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 24 | ||||
| -rw-r--r-- | drivers/acpi/pci_root.c | 130 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 3 | ||||
| -rw-r--r-- | drivers/pci/bus.c | 79 | ||||
| -rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 1 | ||||
| -rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 23 | ||||
| -rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 150 | ||||
| -rw-r--r-- | drivers/pci/iov.c | 9 | ||||
| -rw-r--r-- | drivers/pci/pci-driver.c | 6 | ||||
| -rw-r--r-- | drivers/pci/pci.h | 2 | ||||
| -rw-r--r-- | drivers/pci/probe.c | 37 | ||||
| -rw-r--r-- | drivers/pci/remove.c | 4 | ||||
| -rw-r--r-- | drivers/pci/search.c | 10 | ||||
| -rw-r--r-- | drivers/pci/setup-bus.c | 2 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 9 | ||||
| -rw-r--r-- | include/acpi/acpiosxf.h | 2 | ||||
| -rw-r--r-- | include/linux/pci.h | 1 |
18 files changed, 274 insertions, 219 deletions
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index e050254ae143..0f24148a2b2a 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
| @@ -68,6 +68,7 @@ struct acpi_ec { | |||
| 68 | extern struct acpi_ec *first_ec; | 68 | extern struct acpi_ec *first_ec; |
| 69 | 69 | ||
| 70 | int acpi_pci_root_init(void); | 70 | int acpi_pci_root_init(void); |
| 71 | void acpi_pci_root_hp_init(void); | ||
| 71 | int acpi_ec_init(void); | 72 | int acpi_ec_init(void); |
| 72 | int acpi_ec_ecdt_probe(void); | 73 | int acpi_ec_ecdt_probe(void); |
| 73 | int acpi_boot_ec_enable(void); | 74 | int acpi_boot_ec_enable(void); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 3ff267861541..59ec5f52e849 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -84,8 +84,7 @@ static acpi_osd_handler acpi_irq_handler; | |||
| 84 | static void *acpi_irq_context; | 84 | static void *acpi_irq_context; |
| 85 | static struct workqueue_struct *kacpid_wq; | 85 | static struct workqueue_struct *kacpid_wq; |
| 86 | static struct workqueue_struct *kacpi_notify_wq; | 86 | static struct workqueue_struct *kacpi_notify_wq; |
| 87 | struct workqueue_struct *kacpi_hotplug_wq; | 87 | static struct workqueue_struct *kacpi_hotplug_wq; |
| 88 | EXPORT_SYMBOL(kacpi_hotplug_wq); | ||
| 89 | 88 | ||
| 90 | /* | 89 | /* |
| 91 | * This list of permanent mappings is for memory that may be accessed from | 90 | * This list of permanent mappings is for memory that may be accessed from |
| @@ -1778,3 +1777,24 @@ void acpi_os_set_prepare_sleep(int (*func)(u8 sleep_state, | |||
| 1778 | { | 1777 | { |
| 1779 | __acpi_os_prepare_sleep = func; | 1778 | __acpi_os_prepare_sleep = func; |
| 1780 | } | 1779 | } |
| 1780 | |||
| 1781 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
| 1782 | void (*func)(struct work_struct *work)) | ||
| 1783 | { | ||
| 1784 | struct acpi_hp_work *hp_work; | ||
| 1785 | int ret; | ||
| 1786 | |||
| 1787 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
| 1788 | if (!hp_work) | ||
| 1789 | return; | ||
| 1790 | |||
| 1791 | hp_work->handle = handle; | ||
| 1792 | hp_work->type = type; | ||
| 1793 | hp_work->context = context; | ||
| 1794 | |||
| 1795 | INIT_WORK(&hp_work->work, func); | ||
| 1796 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
| 1797 | if (!ret) | ||
| 1798 | kfree(hp_work); | ||
| 1799 | } | ||
| 1800 | EXPORT_SYMBOL_GPL(alloc_acpi_hp_work); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index bf5108ad4d63..417487a201fb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -655,3 +655,133 @@ int __init acpi_pci_root_init(void) | |||
| 655 | 655 | ||
| 656 | return 0; | 656 | return 0; |
| 657 | } | 657 | } |
| 658 | /* Support root bridge hotplug */ | ||
| 659 | |||
| 660 | static void handle_root_bridge_insertion(acpi_handle handle) | ||
| 661 | { | ||
| 662 | struct acpi_device *device; | ||
| 663 | |||
| 664 | if (!acpi_bus_get_device(handle, &device)) { | ||
| 665 | printk(KERN_DEBUG "acpi device exists...\n"); | ||
| 666 | return; | ||
| 667 | } | ||
| 668 | |||
| 669 | if (acpi_bus_scan(handle)) | ||
| 670 | printk(KERN_ERR "cannot add bridge to acpi list\n"); | ||
| 671 | } | ||
| 672 | |||
| 673 | static void handle_root_bridge_removal(struct acpi_device *device) | ||
| 674 | { | ||
| 675 | struct acpi_eject_event *ej_event; | ||
| 676 | |||
| 677 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); | ||
| 678 | if (!ej_event) { | ||
| 679 | /* Inform firmware the hot-remove operation has error */ | ||
| 680 | (void) acpi_evaluate_hotplug_ost(device->handle, | ||
| 681 | ACPI_NOTIFY_EJECT_REQUEST, | ||
| 682 | ACPI_OST_SC_NON_SPECIFIC_FAILURE, | ||
| 683 | NULL); | ||
| 684 | return; | ||
| 685 | } | ||
| 686 | |||
| 687 | ej_event->device = device; | ||
| 688 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; | ||
| 689 | |||
| 690 | acpi_bus_hot_remove_device(ej_event); | ||
| 691 | } | ||
| 692 | |||
| 693 | static void _handle_hotplug_event_root(struct work_struct *work) | ||
| 694 | { | ||
| 695 | struct acpi_pci_root *root; | ||
| 696 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER }; | ||
| 697 | struct acpi_hp_work *hp_work; | ||
| 698 | acpi_handle handle; | ||
| 699 | u32 type; | ||
| 700 | |||
| 701 | hp_work = container_of(work, struct acpi_hp_work, work); | ||
| 702 | handle = hp_work->handle; | ||
| 703 | type = hp_work->type; | ||
| 704 | |||
| 705 | root = acpi_pci_find_root(handle); | ||
| 706 | |||
| 707 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
| 708 | |||
| 709 | switch (type) { | ||
| 710 | case ACPI_NOTIFY_BUS_CHECK: | ||
| 711 | /* bus enumerate */ | ||
| 712 | printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__, | ||
| 713 | (char *)buffer.pointer); | ||
| 714 | if (!root) | ||
| 715 | handle_root_bridge_insertion(handle); | ||
| 716 | |||
| 717 | break; | ||
| 718 | |||
| 719 | case ACPI_NOTIFY_DEVICE_CHECK: | ||
| 720 | /* device check */ | ||
| 721 | printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__, | ||
| 722 | (char *)buffer.pointer); | ||
| 723 | if (!root) | ||
| 724 | handle_root_bridge_insertion(handle); | ||
| 725 | break; | ||
| 726 | |||
| 727 | case ACPI_NOTIFY_EJECT_REQUEST: | ||
| 728 | /* request device eject */ | ||
| 729 | printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__, | ||
| 730 | (char *)buffer.pointer); | ||
| 731 | if (root) | ||
| 732 | handle_root_bridge_removal(root->device); | ||
| 733 | break; | ||
| 734 | default: | ||
| 735 | printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n", | ||
| 736 | type, (char *)buffer.pointer); | ||
| 737 | break; | ||
| 738 | } | ||
| 739 | |||
| 740 | kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ | ||
| 741 | kfree(buffer.pointer); | ||
| 742 | } | ||
| 743 | |||
| 744 | static void handle_hotplug_event_root(acpi_handle handle, u32 type, | ||
| 745 | void *context) | ||
| 746 | { | ||
| 747 | alloc_acpi_hp_work(handle, type, context, | ||
| 748 | _handle_hotplug_event_root); | ||
| 749 | } | ||
| 750 | |||
| 751 | static acpi_status __init | ||
| 752 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 753 | { | ||
| 754 | acpi_status status; | ||
| 755 | char objname[64]; | ||
| 756 | struct acpi_buffer buffer = { .length = sizeof(objname), | ||
| 757 | .pointer = objname }; | ||
| 758 | int *count = (int *)context; | ||
| 759 | |||
| 760 | if (!acpi_is_root_bridge(handle)) | ||
| 761 | return AE_OK; | ||
| 762 | |||
| 763 | (*count)++; | ||
| 764 | |||
| 765 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
| 766 | |||
| 767 | status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
| 768 | handle_hotplug_event_root, NULL); | ||
| 769 | if (ACPI_FAILURE(status)) | ||
| 770 | printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n", | ||
| 771 | objname, (unsigned int)status); | ||
| 772 | else | ||
| 773 | printk(KERN_DEBUG "acpi root: %s notify handler is installed\n", | ||
| 774 | objname); | ||
| 775 | |||
| 776 | return AE_OK; | ||
| 777 | } | ||
| 778 | |||
| 779 | void __init acpi_pci_root_hp_init(void) | ||
| 780 | { | ||
| 781 | int num = 0; | ||
| 782 | |||
| 783 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
| 784 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); | ||
| 785 | |||
| 786 | printk(KERN_DEBUG "Found %d acpi root devices\n", num); | ||
| 787 | } | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 7c43bdc36abc..bc2f33790e83 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -1706,5 +1706,8 @@ int __init acpi_scan_init(void) | |||
| 1706 | } | 1706 | } |
| 1707 | 1707 | ||
| 1708 | acpi_update_all_gpes(); | 1708 | acpi_update_all_gpes(); |
| 1709 | |||
| 1710 | acpi_pci_root_hp_init(); | ||
| 1711 | |||
| 1709 | return 0; | 1712 | return 0; |
| 1710 | } | 1713 | } |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 847f3ca47bb8..8647dc6f52d0 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
| @@ -161,68 +161,35 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
| 161 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } | 161 | void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } |
| 162 | 162 | ||
| 163 | /** | 163 | /** |
| 164 | * pci_bus_add_device - add a single device | 164 | * pci_bus_add_device - start driver for a single device |
| 165 | * @dev: device to add | 165 | * @dev: device to add |
| 166 | * | 166 | * |
| 167 | * This adds a single pci device to the global | 167 | * This adds add sysfs entries and start device drivers |
| 168 | * device list and adds sysfs and procfs entries | ||
| 169 | */ | 168 | */ |
| 170 | int pci_bus_add_device(struct pci_dev *dev) | 169 | int pci_bus_add_device(struct pci_dev *dev) |
| 171 | { | 170 | { |
| 172 | int retval; | 171 | int retval; |
| 173 | 172 | ||
| 174 | pci_fixup_device(pci_fixup_final, dev); | 173 | /* |
| 175 | 174 | * Can not put in pci_device_add yet because resources | |
| 176 | retval = pcibios_add_device(dev); | 175 | * are not assigned yet for some devices. |
| 177 | if (retval) | 176 | */ |
| 178 | return retval; | ||
| 179 | |||
| 180 | retval = device_add(&dev->dev); | ||
| 181 | if (retval) | ||
| 182 | return retval; | ||
| 183 | |||
| 184 | dev->is_added = 1; | ||
| 185 | pci_proc_attach_device(dev); | ||
| 186 | pci_create_sysfs_dev_files(dev); | 177 | pci_create_sysfs_dev_files(dev); |
| 187 | return 0; | ||
| 188 | } | ||
| 189 | 178 | ||
| 190 | /** | 179 | dev->match_driver = true; |
| 191 | * pci_bus_add_child - add a child bus | 180 | retval = device_attach(&dev->dev); |
| 192 | * @bus: bus to add | 181 | WARN_ON(retval < 0); |
| 193 | * | ||
| 194 | * This adds sysfs entries for a single bus | ||
| 195 | */ | ||
| 196 | int pci_bus_add_child(struct pci_bus *bus) | ||
| 197 | { | ||
| 198 | int retval; | ||
| 199 | 182 | ||
| 200 | if (bus->bridge) | 183 | dev->is_added = 1; |
| 201 | bus->dev.parent = bus->bridge; | ||
| 202 | |||
| 203 | retval = device_register(&bus->dev); | ||
| 204 | if (retval) | ||
| 205 | return retval; | ||
| 206 | |||
| 207 | bus->is_added = 1; | ||
| 208 | |||
| 209 | /* Create legacy_io and legacy_mem files for this bus */ | ||
| 210 | pci_create_legacy_files(bus); | ||
| 211 | 184 | ||
| 212 | return retval; | 185 | return 0; |
| 213 | } | 186 | } |
| 214 | 187 | ||
| 215 | /** | 188 | /** |
| 216 | * pci_bus_add_devices - insert newly discovered PCI devices | 189 | * pci_bus_add_devices - start driver for PCI devices |
| 217 | * @bus: bus to check for new devices | 190 | * @bus: bus to check for new devices |
| 218 | * | 191 | * |
| 219 | * Add newly discovered PCI devices (which are on the bus->devices | 192 | * Start driver for PCI devices and add some sysfs entries. |
| 220 | * list) to the global PCI device list, add the sysfs and procfs | ||
| 221 | * entries. Where a bridge is found, add the discovered bus to | ||
| 222 | * the parents list of child buses, and recurse (breadth-first | ||
| 223 | * to be compatible with 2.4) | ||
| 224 | * | ||
| 225 | * Call hotplug for each new devices. | ||
| 226 | */ | 193 | */ |
| 227 | void pci_bus_add_devices(const struct pci_bus *bus) | 194 | void pci_bus_add_devices(const struct pci_bus *bus) |
| 228 | { | 195 | { |
| @@ -235,36 +202,20 @@ void pci_bus_add_devices(const struct pci_bus *bus) | |||
| 235 | if (dev->is_added) | 202 | if (dev->is_added) |
| 236 | continue; | 203 | continue; |
| 237 | retval = pci_bus_add_device(dev); | 204 | retval = pci_bus_add_device(dev); |
| 238 | if (retval) | ||
| 239 | dev_err(&dev->dev, "Error adding device, continuing\n"); | ||
| 240 | } | 205 | } |
| 241 | 206 | ||
| 242 | list_for_each_entry(dev, &bus->devices, bus_list) { | 207 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 243 | BUG_ON(!dev->is_added); | 208 | BUG_ON(!dev->is_added); |
| 244 | 209 | ||
| 245 | child = dev->subordinate; | 210 | child = dev->subordinate; |
| 246 | /* | 211 | |
| 247 | * If there is an unattached subordinate bus, attach | ||
| 248 | * it and then scan for unattached PCI devices. | ||
| 249 | */ | ||
| 250 | if (!child) | 212 | if (!child) |
| 251 | continue; | 213 | continue; |
| 252 | if (list_empty(&child->node)) { | ||
| 253 | down_write(&pci_bus_sem); | ||
| 254 | list_add_tail(&child->node, &dev->bus->children); | ||
| 255 | up_write(&pci_bus_sem); | ||
| 256 | } | ||
| 257 | pci_bus_add_devices(child); | 214 | pci_bus_add_devices(child); |
| 258 | 215 | ||
| 259 | /* | ||
| 260 | * register the bus with sysfs as the parent is now | ||
| 261 | * properly registered. | ||
| 262 | */ | ||
| 263 | if (child->is_added) | 216 | if (child->is_added) |
| 264 | continue; | 217 | continue; |
| 265 | retval = pci_bus_add_child(child); | 218 | child->is_added = 1; |
| 266 | if (retval) | ||
| 267 | dev_err(&dev->dev, "Error adding bus, continuing\n"); | ||
| 268 | } | 219 | } |
| 269 | } | 220 | } |
| 270 | 221 | ||
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index a1afb5b39ad4..b3ead7ad7b31 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
| @@ -193,7 +193,6 @@ extern void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot); | |||
| 193 | /* acpiphp_glue.c */ | 193 | /* acpiphp_glue.c */ |
| 194 | extern int acpiphp_glue_init (void); | 194 | extern int acpiphp_glue_init (void); |
| 195 | extern void acpiphp_glue_exit (void); | 195 | extern void acpiphp_glue_exit (void); |
| 196 | extern int acpiphp_get_num_slots (void); | ||
| 197 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | 196 | typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); |
| 198 | 197 | ||
| 199 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 198 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 96316b74969f..c2fd3095701f 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
| @@ -50,7 +50,6 @@ | |||
| 50 | bool acpiphp_debug; | 50 | bool acpiphp_debug; |
| 51 | 51 | ||
| 52 | /* local variables */ | 52 | /* local variables */ |
| 53 | static int num_slots; | ||
| 54 | static struct acpiphp_attention_info *attention_info; | 53 | static struct acpiphp_attention_info *attention_info; |
| 55 | 54 | ||
| 56 | #define DRIVER_VERSION "0.5" | 55 | #define DRIVER_VERSION "0.5" |
| @@ -272,25 +271,6 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
| 272 | return 0; | 271 | return 0; |
| 273 | } | 272 | } |
| 274 | 273 | ||
| 275 | static int __init init_acpi(void) | ||
| 276 | { | ||
| 277 | int retval; | ||
| 278 | |||
| 279 | /* initialize internal data structure etc. */ | ||
| 280 | retval = acpiphp_glue_init(); | ||
| 281 | |||
| 282 | /* read initial number of slots */ | ||
| 283 | if (!retval) { | ||
| 284 | num_slots = acpiphp_get_num_slots(); | ||
| 285 | if (num_slots == 0) { | ||
| 286 | acpiphp_glue_exit(); | ||
| 287 | retval = -ENODEV; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | return retval; | ||
| 292 | } | ||
| 293 | |||
| 294 | /** | 274 | /** |
| 295 | * release_slot - free up the memory used by a slot | 275 | * release_slot - free up the memory used by a slot |
| 296 | * @hotplug_slot: slot to free | 276 | * @hotplug_slot: slot to free |
| @@ -379,7 +359,8 @@ static int __init acpiphp_init(void) | |||
| 379 | return 0; | 359 | return 0; |
| 380 | 360 | ||
| 381 | /* read all the ACPI info from the system */ | 361 | /* read all the ACPI info from the system */ |
| 382 | return init_acpi(); | 362 | /* initialize internal data structure etc. */ |
| 363 | return acpiphp_glue_init(); | ||
| 383 | } | 364 | } |
| 384 | 365 | ||
| 385 | 366 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 9e2b1f6dbe41..bd784ff4a244 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
| @@ -543,10 +543,13 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
| 543 | acpi_status status; | 543 | acpi_status status; |
| 544 | acpi_handle handle = bridge->handle; | 544 | acpi_handle handle = bridge->handle; |
| 545 | 545 | ||
| 546 | status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 546 | if (bridge->type != BRIDGE_TYPE_HOST) { |
| 547 | status = acpi_remove_notify_handler(handle, | ||
| 548 | ACPI_SYSTEM_NOTIFY, | ||
| 547 | handle_hotplug_event_bridge); | 549 | handle_hotplug_event_bridge); |
| 548 | if (ACPI_FAILURE(status)) | 550 | if (ACPI_FAILURE(status)) |
| 549 | err("failed to remove notify handler\n"); | 551 | err("failed to remove notify handler\n"); |
| 552 | } | ||
| 550 | 553 | ||
| 551 | if ((bridge->type != BRIDGE_TYPE_HOST) && | 554 | if ((bridge->type != BRIDGE_TYPE_HOST) && |
| 552 | ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { | 555 | ((bridge->flags & BRIDGE_HAS_EJ0) && bridge->func)) { |
| @@ -630,9 +633,6 @@ static void remove_bridge(struct acpi_pci_root *root) | |||
| 630 | bridge = acpiphp_handle_to_bridge(handle); | 633 | bridge = acpiphp_handle_to_bridge(handle); |
| 631 | if (bridge) | 634 | if (bridge) |
| 632 | cleanup_bridge(bridge); | 635 | cleanup_bridge(bridge); |
| 633 | else | ||
| 634 | acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
| 635 | handle_hotplug_event_bridge); | ||
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | static int power_on_slot(struct acpiphp_slot *slot) | 638 | static int power_on_slot(struct acpiphp_slot *slot) |
| @@ -797,6 +797,29 @@ static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) | |||
| 797 | } | 797 | } |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | ||
| 801 | { | ||
| 802 | struct acpiphp_func *func; | ||
| 803 | |||
| 804 | if (!dev->subordinate) | ||
| 805 | return; | ||
| 806 | |||
| 807 | /* quirk, or pcie could set it already */ | ||
| 808 | if (dev->is_hotplug_bridge) | ||
| 809 | return; | ||
| 810 | |||
| 811 | if (PCI_SLOT(dev->devfn) != slot->device) | ||
| 812 | return; | ||
| 813 | |||
| 814 | list_for_each_entry(func, &slot->funcs, sibling) { | ||
| 815 | if (PCI_FUNC(dev->devfn) == func->function) { | ||
| 816 | /* check if this bridge has ejectable slots */ | ||
| 817 | if ((detect_ejectable_slots(func->handle) > 0)) | ||
| 818 | dev->is_hotplug_bridge = 1; | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | } | ||
| 822 | } | ||
| 800 | /** | 823 | /** |
| 801 | * enable_device - enable, configure a slot | 824 | * enable_device - enable, configure a slot |
| 802 | * @slot: slot to be enabled | 825 | * @slot: slot to be enabled |
| @@ -831,8 +854,10 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
| 831 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 854 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
| 832 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { | 855 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { |
| 833 | max = pci_scan_bridge(bus, dev, max, pass); | 856 | max = pci_scan_bridge(bus, dev, max, pass); |
| 834 | if (pass && dev->subordinate) | 857 | if (pass && dev->subordinate) { |
| 858 | check_hotplug_bridge(slot, dev); | ||
| 835 | pci_bus_size_bridges(dev->subordinate); | 859 | pci_bus_size_bridges(dev->subordinate); |
| 860 | } | ||
| 836 | } | 861 | } |
| 837 | } | 862 | } |
| 838 | } | 863 | } |
| @@ -1098,18 +1123,12 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
| 1098 | } | 1123 | } |
| 1099 | 1124 | ||
| 1100 | /* Program resources in newly inserted bridge */ | 1125 | /* Program resources in newly inserted bridge */ |
| 1101 | static int acpiphp_configure_bridge (acpi_handle handle) | 1126 | static int acpiphp_configure_p2p_bridge(acpi_handle handle) |
| 1102 | { | 1127 | { |
| 1103 | struct pci_bus *bus; | 1128 | struct pci_dev *pdev = acpi_get_pci_dev(handle); |
| 1129 | struct pci_bus *bus = pdev->subordinate; | ||
| 1104 | 1130 | ||
| 1105 | if (acpi_is_root_bridge(handle)) { | 1131 | pci_dev_put(pdev); |
| 1106 | struct acpi_pci_root *root = acpi_pci_find_root(handle); | ||
| 1107 | bus = root->bus; | ||
| 1108 | } else { | ||
| 1109 | struct pci_dev *pdev = acpi_get_pci_dev(handle); | ||
| 1110 | bus = pdev->subordinate; | ||
| 1111 | pci_dev_put(pdev); | ||
| 1112 | } | ||
| 1113 | 1132 | ||
| 1114 | pci_bus_size_bridges(bus); | 1133 | pci_bus_size_bridges(bus); |
| 1115 | pci_bus_assign_resources(bus); | 1134 | pci_bus_assign_resources(bus); |
| @@ -1119,7 +1138,7 @@ static int acpiphp_configure_bridge (acpi_handle handle) | |||
| 1119 | return 0; | 1138 | return 0; |
| 1120 | } | 1139 | } |
| 1121 | 1140 | ||
| 1122 | static void handle_bridge_insertion(acpi_handle handle, u32 type) | 1141 | static void handle_p2p_bridge_insertion(acpi_handle handle, u32 type) |
| 1123 | { | 1142 | { |
| 1124 | struct acpi_device *device; | 1143 | struct acpi_device *device; |
| 1125 | 1144 | ||
| @@ -1137,8 +1156,8 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) | |||
| 1137 | err("ACPI device object missing\n"); | 1156 | err("ACPI device object missing\n"); |
| 1138 | return; | 1157 | return; |
| 1139 | } | 1158 | } |
| 1140 | if (!acpiphp_configure_bridge(handle)) | 1159 | if (!acpiphp_configure_p2p_bridge(handle)) |
| 1141 | add_bridge(handle); | 1160 | add_p2p_bridge(handle); |
| 1142 | else | 1161 | else |
| 1143 | err("cannot configure and start bridge\n"); | 1162 | err("cannot configure and start bridge\n"); |
| 1144 | 1163 | ||
| @@ -1178,34 +1197,6 @@ check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
| 1178 | return AE_OK ; | 1197 | return AE_OK ; |
| 1179 | } | 1198 | } |
| 1180 | 1199 | ||
| 1181 | struct acpiphp_hp_work { | ||
| 1182 | struct work_struct work; | ||
| 1183 | acpi_handle handle; | ||
| 1184 | u32 type; | ||
| 1185 | void *context; | ||
| 1186 | }; | ||
| 1187 | |||
| 1188 | static void alloc_acpiphp_hp_work(acpi_handle handle, u32 type, | ||
| 1189 | void *context, | ||
| 1190 | void (*func)(struct work_struct *work)) | ||
| 1191 | { | ||
| 1192 | struct acpiphp_hp_work *hp_work; | ||
| 1193 | int ret; | ||
| 1194 | |||
| 1195 | hp_work = kmalloc(sizeof(*hp_work), GFP_KERNEL); | ||
| 1196 | if (!hp_work) | ||
| 1197 | return; | ||
| 1198 | |||
| 1199 | hp_work->handle = handle; | ||
| 1200 | hp_work->type = type; | ||
| 1201 | hp_work->context = context; | ||
| 1202 | |||
| 1203 | INIT_WORK(&hp_work->work, func); | ||
| 1204 | ret = queue_work(kacpi_hotplug_wq, &hp_work->work); | ||
| 1205 | if (!ret) | ||
| 1206 | kfree(hp_work); | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | static void _handle_hotplug_event_bridge(struct work_struct *work) | 1200 | static void _handle_hotplug_event_bridge(struct work_struct *work) |
| 1210 | { | 1201 | { |
| 1211 | struct acpiphp_bridge *bridge; | 1202 | struct acpiphp_bridge *bridge; |
| @@ -1214,17 +1205,17 @@ static void _handle_hotplug_event_bridge(struct work_struct *work) | |||
| 1214 | .pointer = objname }; | 1205 | .pointer = objname }; |
| 1215 | struct acpi_device *device; | 1206 | struct acpi_device *device; |
| 1216 | int num_sub_bridges = 0; | 1207 | int num_sub_bridges = 0; |
| 1217 | struct acpiphp_hp_work *hp_work; | 1208 | struct acpi_hp_work *hp_work; |
| 1218 | acpi_handle handle; | 1209 | acpi_handle handle; |
| 1219 | u32 type; | 1210 | u32 type; |
| 1220 | 1211 | ||
| 1221 | hp_work = container_of(work, struct acpiphp_hp_work, work); | 1212 | hp_work = container_of(work, struct acpi_hp_work, work); |
| 1222 | handle = hp_work->handle; | 1213 | handle = hp_work->handle; |
| 1223 | type = hp_work->type; | 1214 | type = hp_work->type; |
| 1224 | 1215 | ||
| 1225 | if (acpi_bus_get_device(handle, &device)) { | 1216 | if (acpi_bus_get_device(handle, &device)) { |
| 1226 | /* This bridge must have just been physically inserted */ | 1217 | /* This bridge must have just been physically inserted */ |
| 1227 | handle_bridge_insertion(handle, type); | 1218 | handle_p2p_bridge_insertion(handle, type); |
| 1228 | goto out; | 1219 | goto out; |
| 1229 | } | 1220 | } |
| 1230 | 1221 | ||
| @@ -1321,8 +1312,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, | |||
| 1321 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1312 | * For now just re-add this work to the kacpi_hotplug_wq so we |
| 1322 | * don't deadlock on hotplug actions. | 1313 | * don't deadlock on hotplug actions. |
| 1323 | */ | 1314 | */ |
| 1324 | alloc_acpiphp_hp_work(handle, type, context, | 1315 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge); |
| 1325 | _handle_hotplug_event_bridge); | ||
| 1326 | } | 1316 | } |
| 1327 | 1317 | ||
| 1328 | static void _handle_hotplug_event_func(struct work_struct *work) | 1318 | static void _handle_hotplug_event_func(struct work_struct *work) |
| @@ -1331,12 +1321,12 @@ static void _handle_hotplug_event_func(struct work_struct *work) | |||
| 1331 | char objname[64]; | 1321 | char objname[64]; |
| 1332 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1322 | struct acpi_buffer buffer = { .length = sizeof(objname), |
| 1333 | .pointer = objname }; | 1323 | .pointer = objname }; |
| 1334 | struct acpiphp_hp_work *hp_work; | 1324 | struct acpi_hp_work *hp_work; |
| 1335 | acpi_handle handle; | 1325 | acpi_handle handle; |
| 1336 | u32 type; | 1326 | u32 type; |
| 1337 | void *context; | 1327 | void *context; |
| 1338 | 1328 | ||
| 1339 | hp_work = container_of(work, struct acpiphp_hp_work, work); | 1329 | hp_work = container_of(work, struct acpi_hp_work, work); |
| 1340 | handle = hp_work->handle; | 1330 | handle = hp_work->handle; |
| 1341 | type = hp_work->type; | 1331 | type = hp_work->type; |
| 1342 | context = hp_work->context; | 1332 | context = hp_work->context; |
| @@ -1397,23 +1387,7 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
| 1397 | * For now just re-add this work to the kacpi_hotplug_wq so we | 1387 | * For now just re-add this work to the kacpi_hotplug_wq so we |
| 1398 | * don't deadlock on hotplug actions. | 1388 | * don't deadlock on hotplug actions. |
| 1399 | */ | 1389 | */ |
| 1400 | alloc_acpiphp_hp_work(handle, type, context, | 1390 | alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_func); |
| 1401 | _handle_hotplug_event_func); | ||
| 1402 | } | ||
| 1403 | |||
| 1404 | static acpi_status | ||
| 1405 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
| 1406 | { | ||
| 1407 | int *count = (int *)context; | ||
| 1408 | |||
| 1409 | if (!acpi_is_root_bridge(handle)) | ||
| 1410 | return AE_OK; | ||
| 1411 | |||
| 1412 | (*count)++; | ||
| 1413 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | ||
| 1414 | handle_hotplug_event_bridge, NULL); | ||
| 1415 | |||
| 1416 | return AE_OK ; | ||
| 1417 | } | 1391 | } |
| 1418 | 1392 | ||
| 1419 | static struct acpi_pci_driver acpi_pci_hp_driver = { | 1393 | static struct acpi_pci_driver acpi_pci_hp_driver = { |
| @@ -1426,15 +1400,7 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { | |||
| 1426 | */ | 1400 | */ |
| 1427 | int __init acpiphp_glue_init(void) | 1401 | int __init acpiphp_glue_init(void) |
| 1428 | { | 1402 | { |
| 1429 | int num = 0; | 1403 | acpi_pci_register_driver(&acpi_pci_hp_driver); |
| 1430 | |||
| 1431 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
| 1432 | ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL); | ||
| 1433 | |||
| 1434 | if (num <= 0) | ||
| 1435 | return -1; | ||
| 1436 | else | ||
| 1437 | acpi_pci_register_driver(&acpi_pci_hp_driver); | ||
| 1438 | 1404 | ||
| 1439 | return 0; | 1405 | return 0; |
| 1440 | } | 1406 | } |
| @@ -1450,28 +1416,6 @@ void acpiphp_glue_exit(void) | |||
| 1450 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); | 1416 | acpi_pci_unregister_driver(&acpi_pci_hp_driver); |
| 1451 | } | 1417 | } |
| 1452 | 1418 | ||
| 1453 | |||
| 1454 | /** | ||
| 1455 | * acpiphp_get_num_slots - count number of slots in a system | ||
| 1456 | */ | ||
| 1457 | int __init acpiphp_get_num_slots(void) | ||
| 1458 | { | ||
| 1459 | struct acpiphp_bridge *bridge; | ||
| 1460 | int num_slots = 0; | ||
| 1461 | |||
| 1462 | list_for_each_entry(bridge, &bridge_list, list) { | ||
| 1463 | dbg("Bus %04x:%02x has %d slot%s\n", | ||
| 1464 | pci_domain_nr(bridge->pci_bus), | ||
| 1465 | bridge->pci_bus->number, bridge->nr_slots, | ||
| 1466 | bridge->nr_slots == 1 ? "" : "s"); | ||
| 1467 | num_slots += bridge->nr_slots; | ||
| 1468 | } | ||
| 1469 | |||
| 1470 | dbg("Total %d slots\n", num_slots); | ||
| 1471 | return num_slots; | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | |||
| 1475 | /** | 1419 | /** |
| 1476 | * acpiphp_enable_slot - power on slot | 1420 | * acpiphp_enable_slot - power on slot |
| 1477 | * @slot: ACPI PHP slot | 1421 | * @slot: ACPI PHP slot |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index bafd2bbcaf65..f8720afe0537 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
| @@ -48,12 +48,7 @@ static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) | |||
| 48 | return NULL; | 48 | return NULL; |
| 49 | 49 | ||
| 50 | pci_bus_insert_busn_res(child, busnr, busnr); | 50 | pci_bus_insert_busn_res(child, busnr, busnr); |
| 51 | child->dev.parent = bus->bridge; | 51 | bus->is_added = 1; |
| 52 | rc = pci_bus_add_child(child); | ||
| 53 | if (rc) { | ||
| 54 | pci_remove_bus(child); | ||
| 55 | return NULL; | ||
| 56 | } | ||
| 57 | 52 | ||
| 58 | return child; | 53 | return child; |
| 59 | } | 54 | } |
| @@ -123,8 +118,6 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) | |||
| 123 | virtfn->is_virtfn = 1; | 118 | virtfn->is_virtfn = 1; |
| 124 | 119 | ||
| 125 | rc = pci_bus_add_device(virtfn); | 120 | rc = pci_bus_add_device(virtfn); |
| 126 | if (rc) | ||
| 127 | goto failed1; | ||
| 128 | sprintf(buf, "virtfn%u", id); | 121 | sprintf(buf, "virtfn%u", id); |
| 129 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); | 122 | rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf); |
| 130 | if (rc) | 123 | if (rc) |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index f79cbcd3944b..acdcc3c6ecdd 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
| @@ -1186,9 +1186,13 @@ pci_dev_driver(const struct pci_dev *dev) | |||
| 1186 | static int pci_bus_match(struct device *dev, struct device_driver *drv) | 1186 | static int pci_bus_match(struct device *dev, struct device_driver *drv) |
| 1187 | { | 1187 | { |
| 1188 | struct pci_dev *pci_dev = to_pci_dev(dev); | 1188 | struct pci_dev *pci_dev = to_pci_dev(dev); |
| 1189 | struct pci_driver *pci_drv = to_pci_driver(drv); | 1189 | struct pci_driver *pci_drv; |
| 1190 | const struct pci_device_id *found_id; | 1190 | const struct pci_device_id *found_id; |
| 1191 | 1191 | ||
| 1192 | if (!pci_dev->match_driver) | ||
| 1193 | return 0; | ||
| 1194 | |||
| 1195 | pci_drv = to_pci_driver(drv); | ||
| 1192 | found_id = pci_match_device(pci_drv, pci_dev); | 1196 | found_id = pci_match_device(pci_drv, pci_dev); |
| 1193 | if (found_id) | 1197 | if (found_id) |
| 1194 | return 1; | 1198 | return 1; |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 81b6a8752517..7346ee68f47d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
| @@ -203,8 +203,8 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
| 203 | struct resource *res, unsigned int reg); | 203 | struct resource *res, unsigned int reg); |
| 204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, |
| 205 | enum pci_bar_type *type); | 205 | enum pci_bar_type *type); |
| 206 | extern int pci_bus_add_child(struct pci_bus *bus); | ||
| 207 | extern void pci_configure_ari(struct pci_dev *dev); | 206 | extern void pci_configure_ari(struct pci_dev *dev); |
| 207 | |||
| 208 | /** | 208 | /** |
| 209 | * pci_ari_enabled - query ARI forwarding status | 209 | * pci_ari_enabled - query ARI forwarding status |
| 210 | * @bus: the PCI bus | 210 | * @bus: the PCI bus |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index b4a6ede8f17a..b494066ef32f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -623,6 +623,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
| 623 | { | 623 | { |
| 624 | struct pci_bus *child; | 624 | struct pci_bus *child; |
| 625 | int i; | 625 | int i; |
| 626 | int ret; | ||
| 626 | 627 | ||
| 627 | /* | 628 | /* |
| 628 | * Allocate a new bus, and inherit stuff from the parent.. | 629 | * Allocate a new bus, and inherit stuff from the parent.. |
| @@ -637,8 +638,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
| 637 | child->bus_flags = parent->bus_flags; | 638 | child->bus_flags = parent->bus_flags; |
| 638 | 639 | ||
| 639 | /* initialize some portions of the bus device, but don't register it | 640 | /* initialize some portions of the bus device, but don't register it |
| 640 | * now as the parent is not properly set up yet. This device will get | 641 | * now as the parent is not properly set up yet. |
| 641 | * registered later in pci_bus_add_devices() | ||
| 642 | */ | 642 | */ |
| 643 | child->dev.class = &pcibus_class; | 643 | child->dev.class = &pcibus_class; |
| 644 | dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); | 644 | dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr); |
| @@ -651,11 +651,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
| 651 | child->primary = parent->busn_res.start; | 651 | child->primary = parent->busn_res.start; |
| 652 | child->busn_res.end = 0xff; | 652 | child->busn_res.end = 0xff; |
| 653 | 653 | ||
| 654 | if (!bridge) | 654 | if (!bridge) { |
| 655 | return child; | 655 | child->dev.parent = parent->bridge; |
| 656 | goto add_dev; | ||
| 657 | } | ||
| 656 | 658 | ||
| 657 | child->self = bridge; | 659 | child->self = bridge; |
| 658 | child->bridge = get_device(&bridge->dev); | 660 | child->bridge = get_device(&bridge->dev); |
| 661 | child->dev.parent = child->bridge; | ||
| 659 | pci_set_bus_of_node(child); | 662 | pci_set_bus_of_node(child); |
| 660 | pci_set_bus_speed(child); | 663 | pci_set_bus_speed(child); |
| 661 | 664 | ||
| @@ -666,6 +669,13 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, | |||
| 666 | } | 669 | } |
| 667 | bridge->subordinate = child; | 670 | bridge->subordinate = child; |
| 668 | 671 | ||
| 672 | add_dev: | ||
| 673 | ret = device_register(&child->dev); | ||
| 674 | WARN_ON(ret < 0); | ||
| 675 | |||
| 676 | /* Create legacy_io and legacy_mem files for this bus */ | ||
| 677 | pci_create_legacy_files(child); | ||
| 678 | |||
| 669 | return child; | 679 | return child; |
| 670 | } | 680 | } |
| 671 | 681 | ||
| @@ -1296,10 +1306,12 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
| 1296 | 1306 | ||
| 1297 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1307 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
| 1298 | { | 1308 | { |
| 1309 | int ret; | ||
| 1310 | |||
| 1299 | device_initialize(&dev->dev); | 1311 | device_initialize(&dev->dev); |
| 1300 | dev->dev.release = pci_release_dev; | 1312 | dev->dev.release = pci_release_dev; |
| 1301 | pci_dev_get(dev); | ||
| 1302 | 1313 | ||
| 1314 | set_dev_node(&dev->dev, pcibus_to_node(bus)); | ||
| 1303 | dev->dev.dma_mask = &dev->dma_mask; | 1315 | dev->dev.dma_mask = &dev->dma_mask; |
| 1304 | dev->dev.dma_parms = &dev->dma_parms; | 1316 | dev->dev.dma_parms = &dev->dma_parms; |
| 1305 | dev->dev.coherent_dma_mask = 0xffffffffull; | 1317 | dev->dev.coherent_dma_mask = 0xffffffffull; |
| @@ -1326,6 +1338,17 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
| 1326 | down_write(&pci_bus_sem); | 1338 | down_write(&pci_bus_sem); |
| 1327 | list_add_tail(&dev->bus_list, &bus->devices); | 1339 | list_add_tail(&dev->bus_list, &bus->devices); |
| 1328 | up_write(&pci_bus_sem); | 1340 | up_write(&pci_bus_sem); |
| 1341 | |||
| 1342 | pci_fixup_device(pci_fixup_final, dev); | ||
| 1343 | ret = pcibios_add_device(dev); | ||
| 1344 | WARN_ON(ret < 0); | ||
| 1345 | |||
| 1346 | /* Notifier could use PCI capabilities */ | ||
| 1347 | dev->match_driver = false; | ||
| 1348 | ret = device_add(&dev->dev); | ||
| 1349 | WARN_ON(ret < 0); | ||
| 1350 | |||
| 1351 | pci_proc_attach_device(dev); | ||
| 1329 | } | 1352 | } |
| 1330 | 1353 | ||
| 1331 | struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | 1354 | struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) |
| @@ -1650,13 +1673,13 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
| 1650 | char bus_addr[64]; | 1673 | char bus_addr[64]; |
| 1651 | char *fmt; | 1674 | char *fmt; |
| 1652 | 1675 | ||
| 1653 | |||
| 1654 | b = pci_alloc_bus(); | 1676 | b = pci_alloc_bus(); |
| 1655 | if (!b) | 1677 | if (!b) |
| 1656 | return NULL; | 1678 | return NULL; |
| 1657 | 1679 | ||
| 1658 | b->sysdata = sysdata; | 1680 | b->sysdata = sysdata; |
| 1659 | b->ops = ops; | 1681 | b->ops = ops; |
| 1682 | b->number = b->busn_res.start = bus; | ||
| 1660 | b2 = pci_find_bus(pci_domain_nr(b), bus); | 1683 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
| 1661 | if (b2) { | 1684 | if (b2) { |
| 1662 | /* If we already got to this bus through a different bridge, ignore it */ | 1685 | /* If we already got to this bus through a different bridge, ignore it */ |
| @@ -1695,8 +1718,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
| 1695 | /* Create legacy_io and legacy_mem files for this bus */ | 1718 | /* Create legacy_io and legacy_mem files for this bus */ |
| 1696 | pci_create_legacy_files(b); | 1719 | pci_create_legacy_files(b); |
| 1697 | 1720 | ||
| 1698 | b->number = b->busn_res.start = bus; | ||
| 1699 | |||
| 1700 | if (parent) | 1721 | if (parent) |
| 1701 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1722 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
| 1702 | else | 1723 | else |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 7c0fd9252e6f..fc38c4883e1d 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
| @@ -22,7 +22,7 @@ static void pci_stop_dev(struct pci_dev *dev) | |||
| 22 | if (dev->is_added) { | 22 | if (dev->is_added) { |
| 23 | pci_proc_detach_device(dev); | 23 | pci_proc_detach_device(dev); |
| 24 | pci_remove_sysfs_dev_files(dev); | 24 | pci_remove_sysfs_dev_files(dev); |
| 25 | device_unregister(&dev->dev); | 25 | device_del(&dev->dev); |
| 26 | dev->is_added = 0; | 26 | dev->is_added = 0; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| @@ -37,7 +37,7 @@ static void pci_destroy_dev(struct pci_dev *dev) | |||
| 37 | up_write(&pci_bus_sem); | 37 | up_write(&pci_bus_sem); |
| 38 | 38 | ||
| 39 | pci_free_resources(dev); | 39 | pci_free_resources(dev); |
| 40 | pci_dev_put(dev); | 40 | put_device(&dev->dev); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | void pci_remove_bus(struct pci_bus *bus) | 43 | void pci_remove_bus(struct pci_bus *bus) |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index bf969ba58e59..d0627fa9f368 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
| @@ -319,13 +319,13 @@ int pci_dev_present(const struct pci_device_id *ids) | |||
| 319 | WARN_ON(in_interrupt()); | 319 | WARN_ON(in_interrupt()); |
| 320 | while (ids->vendor || ids->subvendor || ids->class_mask) { | 320 | while (ids->vendor || ids->subvendor || ids->class_mask) { |
| 321 | found = pci_get_dev_by_id(ids, NULL); | 321 | found = pci_get_dev_by_id(ids, NULL); |
| 322 | if (found) | 322 | if (found) { |
| 323 | goto exit; | 323 | pci_dev_put(found); |
| 324 | return 1; | ||
| 325 | } | ||
| 324 | ids++; | 326 | ids++; |
| 325 | } | 327 | } |
| 326 | exit: | 328 | |
| 327 | if (found) | ||
| 328 | return 1; | ||
| 329 | return 0; | 329 | return 0; |
| 330 | } | 330 | } |
| 331 | EXPORT_SYMBOL(pci_dev_present); | 331 | EXPORT_SYMBOL(pci_dev_present); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6d3591d57ea0..7e8739e25b9e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
| @@ -283,7 +283,7 @@ static void assign_requested_resources_sorted(struct list_head *head, | |||
| 283 | idx = res - &dev_res->dev->resource[0]; | 283 | idx = res - &dev_res->dev->resource[0]; |
| 284 | if (resource_size(res) && | 284 | if (resource_size(res) && |
| 285 | pci_assign_resource(dev_res->dev, idx)) { | 285 | pci_assign_resource(dev_res->dev, idx)) { |
| 286 | if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) { | 286 | if (fail_head) { |
| 287 | /* | 287 | /* |
| 288 | * if the failed res is for ROM BAR, and it will | 288 | * if the failed res is for ROM BAR, and it will |
| 289 | * be enabled later, don't add it to the list | 289 | * be enabled later, don't add it to the list |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 526d66384c09..5ce8d5e86734 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -310,6 +310,15 @@ struct acpi_eject_event { | |||
| 310 | u32 event; | 310 | u32 event; |
| 311 | }; | 311 | }; |
| 312 | 312 | ||
| 313 | struct acpi_hp_work { | ||
| 314 | struct work_struct work; | ||
| 315 | acpi_handle handle; | ||
| 316 | u32 type; | ||
| 317 | void *context; | ||
| 318 | }; | ||
| 319 | void alloc_acpi_hp_work(acpi_handle handle, u32 type, void *context, | ||
| 320 | void (*func)(struct work_struct *work)); | ||
| 321 | |||
| 313 | extern struct kobject *acpi_kobj; | 322 | extern struct kobject *acpi_kobj; |
| 314 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); | 323 | extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); |
| 315 | void acpi_bus_private_data_handler(acpi_handle, void *); | 324 | void acpi_bus_private_data_handler(acpi_handle, void *); |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 43152742b46f..66f1fd70e8c2 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
| @@ -193,8 +193,6 @@ void acpi_os_fixed_event_count(u32 fixed_event_number); | |||
| 193 | /* | 193 | /* |
| 194 | * Threads and Scheduling | 194 | * Threads and Scheduling |
| 195 | */ | 195 | */ |
| 196 | extern struct workqueue_struct *kacpi_hotplug_wq; | ||
| 197 | |||
| 198 | acpi_thread_id acpi_os_get_thread_id(void); | 196 | acpi_thread_id acpi_os_get_thread_id(void); |
| 199 | 197 | ||
| 200 | acpi_status | 198 | acpi_status |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 6860f4dec997..056d3d66b976 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -286,6 +286,7 @@ struct pci_dev { | |||
| 286 | unsigned int irq; | 286 | unsigned int irq; |
| 287 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ | 287 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ |
| 288 | 288 | ||
| 289 | bool match_driver; /* Skip attaching driver */ | ||
| 289 | /* These fields are used by common fixups */ | 290 | /* These fields are used by common fixups */ |
| 290 | unsigned int transparent:1; /* Transparent PCI bridge */ | 291 | unsigned int transparent:1; /* Transparent PCI bridge */ |
| 291 | unsigned int multifunction:1;/* Part of multi-function device */ | 292 | unsigned int multifunction:1;/* Part of multi-function device */ |
