aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 00:18:18 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 00:18:18 -0500
commit556f12f602ac0a18a82ca83e9f8e8547688fc633 (patch)
treed4051f6dd57968c8e8e660ad117c5bedc2aa7e8e /drivers/acpi/pci_root.c
parentfffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (diff)
parent018ba0a6efada61b9bc17500101d81c3d35807c2 (diff)
Merge tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: "Host bridge hotplug - Major overhaul of ACPI host bridge add/start (Rafael Wysocki, Yinghai Lu) - Major overhaul of PCI/ACPI binding (Rafael Wysocki, Yinghai Lu) - Split out ACPI host bridge and ACPI PCI device hotplug (Yinghai Lu) - Stop caching _PRT and make independent of bus numbers (Yinghai Lu) PCI device hotplug - Clean up cpqphp dead code (Sasha Levin) - Disable ARI unless device and upstream bridge support it (Yijing Wang) - Initialize all hot-added devices (not functions 0-7) (Yijing Wang) Power management - Don't touch ASPM if disabled (Joe Lawrence) - Fix ASPM link state management (Myron Stowe) Miscellaneous - Fix PCI_EXP_FLAGS accessor (Alex Williamson) - Disable Bus Master in pci_device_shutdown (Konstantin Khlebnikov) - Document hotplug resource and MPS parameters (Yijing Wang) - Add accessor for PCIe capabilities (Myron Stowe) - Drop pciehp suspend/resume messages (Paul Bolle) - Make pci_slot built-in only (not a module) (Jiang Liu) - Remove unused PCI/ACPI bind ops (Jiang Liu) - Removed used pci_root_bus (Bjorn Helgaas)" * tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (51 commits) PCI/ACPI: Don't cache _PRT, and don't associate them with bus numbers PCI: Fix PCI Express Capability accessors for PCI_EXP_FLAGS ACPI / PCI: Make pci_slot built-in only, not a module PCI/PM: Clear state_saved during suspend PCI: Use atomic_inc_return() rather than atomic_add_return() PCI: Catch attempts to disable already-disabled devices PCI: Disable Bus Master unconditionally in pci_device_shutdown() PCI: acpiphp: Remove dead code for PCI host bridge hotplug PCI: acpiphp: Create companion ACPI devices before creating PCI devices PCI: Remove unused "rc" in virtfn_add_bus() PCI: pciehp: Drop suspend/resume ENTRY messages PCI/ASPM: Don't touch ASPM if forcibly disabled PCI/ASPM: Deallocate upstream link state even if device is not PCIe PCI: Document MPS parameters pci=pcie_bus_safe, pci=pcie_bus_perf, etc PCI: Document hpiosize= and hpmemsize= resource reservation parameters PCI: Use PCI Express Capability accessor PCI: Introduce accessor to retrieve PCIe Capabilities Register PCI: Put pci_dev in device tree as early as possible PCI: Skip attaching driver in device_add() PCI: acpiphp: Keep driver loaded even if no slots found ...
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c170
1 files changed, 133 insertions, 37 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b3cc69c5caf1..0ac546d5e53f 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -103,24 +103,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
103} 103}
104EXPORT_SYMBOL(acpi_pci_unregister_driver); 104EXPORT_SYMBOL(acpi_pci_unregister_driver);
105 105
106acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
107{
108 struct acpi_pci_root *root;
109 acpi_handle handle = NULL;
110
111 mutex_lock(&acpi_pci_root_lock);
112 list_for_each_entry(root, &acpi_pci_roots, node)
113 if ((root->segment == (u16) seg) &&
114 (root->secondary.start == (u16) bus)) {
115 handle = root->device->handle;
116 break;
117 }
118 mutex_unlock(&acpi_pci_root_lock);
119 return handle;
120}
121
122EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
123
124/** 106/**
125 * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge 107 * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
126 * @handle - the ACPI CA node in question. 108 * @handle - the ACPI CA node in question.
@@ -431,7 +413,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
431 acpi_status status; 413 acpi_status status;
432 int result; 414 int result;
433 struct acpi_pci_root *root; 415 struct acpi_pci_root *root;
434 acpi_handle handle;
435 struct acpi_pci_driver *driver; 416 struct acpi_pci_driver *driver;
436 u32 flags, base_flags; 417 u32 flags, base_flags;
437 bool is_osc_granted = false; 418 bool is_osc_granted = false;
@@ -486,16 +467,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
486 acpi_device_name(device), acpi_device_bid(device), 467 acpi_device_name(device), acpi_device_bid(device),
487 root->segment, &root->secondary); 468 root->segment, &root->secondary);
488 469
489 /*
490 * PCI Routing Table
491 * -----------------
492 * Evaluate and parse _PRT, if exists.
493 */
494 status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
495 if (ACPI_SUCCESS(status))
496 result = acpi_pci_irq_add_prt(device->handle, root->segment,
497 root->secondary.start);
498
499 root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); 470 root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle);
500 471
501 /* 472 /*
@@ -597,8 +568,10 @@ static int acpi_pci_root_add(struct acpi_device *device,
597 if (device->wakeup.flags.run_wake) 568 if (device->wakeup.flags.run_wake)
598 device_set_run_wake(root->bus->bridge, true); 569 device_set_run_wake(root->bus->bridge, true);
599 570
600 if (system_state != SYSTEM_BOOTING) 571 if (system_state != SYSTEM_BOOTING) {
572 pcibios_resource_survey_bus(root->bus);
601 pci_assign_unassigned_bus_resources(root->bus); 573 pci_assign_unassigned_bus_resources(root->bus);
574 }
602 575
603 mutex_lock(&acpi_pci_root_lock); 576 mutex_lock(&acpi_pci_root_lock);
604 list_for_each_entry(driver, &acpi_pci_drivers, node) 577 list_for_each_entry(driver, &acpi_pci_drivers, node)
@@ -618,7 +591,6 @@ out_del_root:
618 list_del(&root->node); 591 list_del(&root->node);
619 mutex_unlock(&acpi_pci_root_lock); 592 mutex_unlock(&acpi_pci_root_lock);
620 593
621 acpi_pci_irq_del_prt(root->segment, root->secondary.start);
622end: 594end:
623 kfree(root); 595 kfree(root);
624 return result; 596 return result;
@@ -626,8 +598,6 @@ end:
626 598
627static void acpi_pci_root_remove(struct acpi_device *device) 599static void acpi_pci_root_remove(struct acpi_device *device)
628{ 600{
629 acpi_status status;
630 acpi_handle handle;
631 struct acpi_pci_root *root = acpi_driver_data(device); 601 struct acpi_pci_root *root = acpi_driver_data(device);
632 struct acpi_pci_driver *driver; 602 struct acpi_pci_driver *driver;
633 603
@@ -642,10 +612,6 @@ static void acpi_pci_root_remove(struct acpi_device *device)
642 device_set_run_wake(root->bus->bridge, false); 612 device_set_run_wake(root->bus->bridge, false);
643 pci_acpi_remove_bus_pm_notifier(device); 613 pci_acpi_remove_bus_pm_notifier(device);
644 614
645 status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
646 if (ACPI_SUCCESS(status))
647 acpi_pci_irq_del_prt(root->segment, root->secondary.start);
648
649 pci_remove_root_bus(root->bus); 615 pci_remove_root_bus(root->bus);
650 616
651 mutex_lock(&acpi_pci_root_lock); 617 mutex_lock(&acpi_pci_root_lock);
@@ -663,3 +629,133 @@ void __init acpi_pci_root_init(void)
663 acpi_scan_add_handler(&pci_root_handler); 629 acpi_scan_add_handler(&pci_root_handler);
664 } 630 }
665} 631}
632/* Support root bridge hotplug */
633
634static void handle_root_bridge_insertion(acpi_handle handle)
635{
636 struct acpi_device *device;
637
638 if (!acpi_bus_get_device(handle, &device)) {
639 printk(KERN_DEBUG "acpi device exists...\n");
640 return;
641 }
642
643 if (acpi_bus_scan(handle))
644 printk(KERN_ERR "cannot add bridge to acpi list\n");
645}
646
647static void handle_root_bridge_removal(struct acpi_device *device)
648{
649 struct acpi_eject_event *ej_event;
650
651 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
652 if (!ej_event) {
653 /* Inform firmware the hot-remove operation has error */
654 (void) acpi_evaluate_hotplug_ost(device->handle,
655 ACPI_NOTIFY_EJECT_REQUEST,
656 ACPI_OST_SC_NON_SPECIFIC_FAILURE,
657 NULL);
658 return;
659 }
660
661 ej_event->device = device;
662 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
663
664 acpi_bus_hot_remove_device(ej_event);
665}
666
667static void _handle_hotplug_event_root(struct work_struct *work)
668{
669 struct acpi_pci_root *root;
670 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
671 struct acpi_hp_work *hp_work;
672 acpi_handle handle;
673 u32 type;
674
675 hp_work = container_of(work, struct acpi_hp_work, work);
676 handle = hp_work->handle;
677 type = hp_work->type;
678
679 root = acpi_pci_find_root(handle);
680
681 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
682
683 switch (type) {
684 case ACPI_NOTIFY_BUS_CHECK:
685 /* bus enumerate */
686 printk(KERN_DEBUG "%s: Bus check notify on %s\n", __func__,
687 (char *)buffer.pointer);
688 if (!root)
689 handle_root_bridge_insertion(handle);
690
691 break;
692
693 case ACPI_NOTIFY_DEVICE_CHECK:
694 /* device check */
695 printk(KERN_DEBUG "%s: Device check notify on %s\n", __func__,
696 (char *)buffer.pointer);
697 if (!root)
698 handle_root_bridge_insertion(handle);
699 break;
700
701 case ACPI_NOTIFY_EJECT_REQUEST:
702 /* request device eject */
703 printk(KERN_DEBUG "%s: Device eject notify on %s\n", __func__,
704 (char *)buffer.pointer);
705 if (root)
706 handle_root_bridge_removal(root->device);
707 break;
708 default:
709 printk(KERN_WARNING "notify_handler: unknown event type 0x%x for %s\n",
710 type, (char *)buffer.pointer);
711 break;
712 }
713
714 kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
715 kfree(buffer.pointer);
716}
717
718static void handle_hotplug_event_root(acpi_handle handle, u32 type,
719 void *context)
720{
721 alloc_acpi_hp_work(handle, type, context,
722 _handle_hotplug_event_root);
723}
724
725static acpi_status __init
726find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv)
727{
728 acpi_status status;
729 char objname[64];
730 struct acpi_buffer buffer = { .length = sizeof(objname),
731 .pointer = objname };
732 int *count = (int *)context;
733
734 if (!acpi_is_root_bridge(handle))
735 return AE_OK;
736
737 (*count)++;
738
739 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
740
741 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
742 handle_hotplug_event_root, NULL);
743 if (ACPI_FAILURE(status))
744 printk(KERN_DEBUG "acpi root: %s notify handler is not installed, exit status: %u\n",
745 objname, (unsigned int)status);
746 else
747 printk(KERN_DEBUG "acpi root: %s notify handler is installed\n",
748 objname);
749
750 return AE_OK;
751}
752
753void __init acpi_pci_root_hp_init(void)
754{
755 int num = 0;
756
757 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
758 ACPI_UINT32_MAX, find_root_bridges, NULL, &num, NULL);
759
760 printk(KERN_DEBUG "Found %d acpi root devices\n", num);
761}