aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/acpiphp_glue.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 15:18:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 15:18:16 -0500
commit11bd04f6f35621193311c32e0721142b073a7794 (patch)
tree00979740582bb26e8d3756bf3526c85f19f66a46 /drivers/pci/hotplug/acpiphp_glue.c
parent4e2ccdb0409146f8cf64a11b6ef82a9c928ced2a (diff)
parent9e0b5b2c447ad0caa075a5cfef86def62e1782ff (diff)
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (109 commits) PCI: fix coding style issue in pci_save_state() PCI: add pci_request_acs PCI: fix BUG_ON triggered by logical PCIe root port removal PCI: remove ifdefed pci_cleanup_aer_correct_error_status PCI: unconditionally clear AER uncorr status register during cleanup x86/PCI: claim SR-IOV BARs in pcibios_allocate_resource PCI: portdrv: remove redundant definitions PCI: portdrv: remove unnecessary struct pcie_port_data PCI: portdrv: minor cleanup for pcie_port_device_register PCI: portdrv: add missing irq cleanup PCI: portdrv: enable device before irq initialization PCI: portdrv: cleanup service irqs initialization PCI: portdrv: check capabilities first PCI: portdrv: move PME capability check PCI: portdrv: remove redundant pcie type calculation PCI: portdrv: cleanup pcie_device registration PCI: portdrv: remove redundant pcie_port_device_probe PCI: Always set prefetchable base/limit upper32 registers PCI: read-modify-write the pcie device control register when initiating pcie flr PCI: show dma_mask bits in /sys ... Fixed up conflicts in: arch/x86/kernel/amd_iommu_init.c drivers/pci/dmar.c drivers/pci/hotplug/acpiphp_glue.c
Diffstat (limited to 'drivers/pci/hotplug/acpiphp_glue.c')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c248
1 files changed, 17 insertions, 231 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index df1b0ea089d1..8e952fdab764 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -52,8 +52,6 @@
52#include "acpiphp.h" 52#include "acpiphp.h"
53 53
54static LIST_HEAD(bridge_list); 54static LIST_HEAD(bridge_list);
55static LIST_HEAD(ioapic_list);
56static DEFINE_SPINLOCK(ioapic_list_lock);
57 55
58#define MY_NAME "acpiphp_glue" 56#define MY_NAME "acpiphp_glue"
59 57
@@ -311,17 +309,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge)
311/* find acpiphp_func from acpiphp_bridge */ 309/* find acpiphp_func from acpiphp_bridge */
312static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) 310static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle)
313{ 311{
314 struct list_head *node, *l;
315 struct acpiphp_bridge *bridge; 312 struct acpiphp_bridge *bridge;
316 struct acpiphp_slot *slot; 313 struct acpiphp_slot *slot;
317 struct acpiphp_func *func; 314 struct acpiphp_func *func;
318 315
319 list_for_each(node, &bridge_list) { 316 list_for_each_entry(bridge, &bridge_list, list) {
320 bridge = list_entry(node, struct acpiphp_bridge, list);
321 for (slot = bridge->slots; slot; slot = slot->next) { 317 for (slot = bridge->slots; slot; slot = slot->next) {
322 list_for_each(l, &slot->funcs) { 318 list_for_each_entry(func, &slot->funcs, sibling) {
323 func = list_entry(l, struct acpiphp_func,
324 sibling);
325 if (func->handle == handle) 319 if (func->handle == handle)
326 return func; 320 return func;
327 } 321 }
@@ -495,21 +489,19 @@ static int add_bridge(acpi_handle handle)
495 489
496static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) 490static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle)
497{ 491{
498 struct list_head *head; 492 struct acpiphp_bridge *bridge;
499 list_for_each(head, &bridge_list) { 493
500 struct acpiphp_bridge *bridge = list_entry(head, 494 list_for_each_entry(bridge, &bridge_list, list)
501 struct acpiphp_bridge, list);
502 if (bridge->handle == handle) 495 if (bridge->handle == handle)
503 return bridge; 496 return bridge;
504 }
505 497
506 return NULL; 498 return NULL;
507} 499}
508 500
509static void cleanup_bridge(struct acpiphp_bridge *bridge) 501static void cleanup_bridge(struct acpiphp_bridge *bridge)
510{ 502{
511 struct list_head *list, *tmp; 503 struct acpiphp_slot *slot, *next;
512 struct acpiphp_slot *slot; 504 struct acpiphp_func *func, *tmp;
513 acpi_status status; 505 acpi_status status;
514 acpi_handle handle = bridge->handle; 506 acpi_handle handle = bridge->handle;
515 507
@@ -530,10 +522,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
530 522
531 slot = bridge->slots; 523 slot = bridge->slots;
532 while (slot) { 524 while (slot) {
533 struct acpiphp_slot *next = slot->next; 525 next = slot->next;
534 list_for_each_safe (list, tmp, &slot->funcs) { 526 list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) {
535 struct acpiphp_func *func;
536 func = list_entry(list, struct acpiphp_func, sibling);
537 if (is_dock_device(func->handle)) { 527 if (is_dock_device(func->handle)) {
538 unregister_hotplug_dock_device(func->handle); 528 unregister_hotplug_dock_device(func->handle);
539 unregister_dock_notifier(&func->nb); 529 unregister_dock_notifier(&func->nb);
@@ -545,7 +535,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
545 if (ACPI_FAILURE(status)) 535 if (ACPI_FAILURE(status))
546 err("failed to remove notify handler\n"); 536 err("failed to remove notify handler\n");
547 } 537 }
548 list_del(list); 538 list_del(&func->sibling);
549 kfree(func); 539 kfree(func);
550 } 540 }
551 acpiphp_unregister_hotplug_slot(slot); 541 acpiphp_unregister_hotplug_slot(slot);
@@ -606,204 +596,17 @@ static void remove_bridge(acpi_handle handle)
606 handle_hotplug_event_bridge); 596 handle_hotplug_event_bridge);
607} 597}
608 598
609static struct pci_dev * get_apic_pci_info(acpi_handle handle)
610{
611 struct pci_dev *dev;
612
613 dev = acpi_get_pci_dev(handle);
614 if (!dev)
615 return NULL;
616
617 if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) &&
618 (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC))
619 {
620 pci_dev_put(dev);
621 return NULL;
622 }
623
624 return dev;
625}
626
627static int get_gsi_base(acpi_handle handle, u32 *gsi_base)
628{
629 acpi_status status;
630 int result = -1;
631 unsigned long long gsb;
632 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
633 union acpi_object *obj;
634 void *table;
635
636 status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb);
637 if (ACPI_SUCCESS(status)) {
638 *gsi_base = (u32)gsb;
639 return 0;
640 }
641
642 status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer);
643 if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer)
644 return -1;
645
646 obj = buffer.pointer;
647 if (obj->type != ACPI_TYPE_BUFFER)
648 goto out;
649
650 table = obj->buffer.pointer;
651 switch (((struct acpi_subtable_header *)table)->type) {
652 case ACPI_MADT_TYPE_IO_SAPIC:
653 *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base;
654 result = 0;
655 break;
656 case ACPI_MADT_TYPE_IO_APIC:
657 *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base;
658 result = 0;
659 break;
660 default:
661 break;
662 }
663 out:
664 kfree(buffer.pointer);
665 return result;
666}
667
668static acpi_status
669ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv)
670{
671 acpi_status status;
672 unsigned long long sta;
673 acpi_handle tmp;
674 struct pci_dev *pdev;
675 u32 gsi_base;
676 u64 phys_addr;
677 struct acpiphp_ioapic *ioapic;
678
679 /* Evaluate _STA if present */
680 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
681 if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
682 return AE_CTRL_DEPTH;
683
684 /* Scan only PCI bus scope */
685 status = acpi_get_handle(handle, "_HID", &tmp);
686 if (ACPI_SUCCESS(status))
687 return AE_CTRL_DEPTH;
688
689 if (get_gsi_base(handle, &gsi_base))
690 return AE_OK;
691
692 ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL);
693 if (!ioapic)
694 return AE_NO_MEMORY;
695
696 pdev = get_apic_pci_info(handle);
697 if (!pdev)
698 goto exit_kfree;
699
700 if (pci_enable_device(pdev))
701 goto exit_pci_dev_put;
702
703 pci_set_master(pdev);
704
705 if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)"))
706 goto exit_pci_disable_device;
707
708 phys_addr = pci_resource_start(pdev, 0);
709 if (acpi_register_ioapic(handle, phys_addr, gsi_base))
710 goto exit_pci_release_region;
711
712 ioapic->gsi_base = gsi_base;
713 ioapic->dev = pdev;
714 spin_lock(&ioapic_list_lock);
715 list_add_tail(&ioapic->list, &ioapic_list);
716 spin_unlock(&ioapic_list_lock);
717
718 return AE_OK;
719
720 exit_pci_release_region:
721 pci_release_region(pdev, 0);
722 exit_pci_disable_device:
723 pci_disable_device(pdev);
724 exit_pci_dev_put:
725 pci_dev_put(pdev);
726 exit_kfree:
727 kfree(ioapic);
728
729 return AE_OK;
730}
731
732static acpi_status
733ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv)
734{
735 acpi_status status;
736 unsigned long long sta;
737 acpi_handle tmp;
738 u32 gsi_base;
739 struct acpiphp_ioapic *pos, *n, *ioapic = NULL;
740
741 /* Evaluate _STA if present */
742 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
743 if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL)
744 return AE_CTRL_DEPTH;
745
746 /* Scan only PCI bus scope */
747 status = acpi_get_handle(handle, "_HID", &tmp);
748 if (ACPI_SUCCESS(status))
749 return AE_CTRL_DEPTH;
750
751 if (get_gsi_base(handle, &gsi_base))
752 return AE_OK;
753
754 acpi_unregister_ioapic(handle, gsi_base);
755
756 spin_lock(&ioapic_list_lock);
757 list_for_each_entry_safe(pos, n, &ioapic_list, list) {
758 if (pos->gsi_base != gsi_base)
759 continue;
760 ioapic = pos;
761 list_del(&ioapic->list);
762 break;
763 }
764 spin_unlock(&ioapic_list_lock);
765
766 if (!ioapic)
767 return AE_OK;
768
769 pci_release_region(ioapic->dev, 0);
770 pci_disable_device(ioapic->dev);
771 pci_dev_put(ioapic->dev);
772 kfree(ioapic);
773
774 return AE_OK;
775}
776
777static int acpiphp_configure_ioapics(acpi_handle handle)
778{
779 ioapic_add(handle, 0, NULL, NULL);
780 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
781 ACPI_UINT32_MAX, ioapic_add, NULL, NULL, NULL);
782 return 0;
783}
784
785static int acpiphp_unconfigure_ioapics(acpi_handle handle)
786{
787 ioapic_remove(handle, 0, NULL, NULL);
788 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle,
789 ACPI_UINT32_MAX, ioapic_remove, NULL, NULL, NULL);
790 return 0;
791}
792
793static int power_on_slot(struct acpiphp_slot *slot) 599static int power_on_slot(struct acpiphp_slot *slot)
794{ 600{
795 acpi_status status; 601 acpi_status status;
796 struct acpiphp_func *func; 602 struct acpiphp_func *func;
797 struct list_head *l;
798 int retval = 0; 603 int retval = 0;
799 604
800 /* if already enabled, just skip */ 605 /* if already enabled, just skip */
801 if (slot->flags & SLOT_POWEREDON) 606 if (slot->flags & SLOT_POWEREDON)
802 goto err_exit; 607 goto err_exit;
803 608
804 list_for_each (l, &slot->funcs) { 609 list_for_each_entry(func, &slot->funcs, sibling) {
805 func = list_entry(l, struct acpiphp_func, sibling);
806
807 if (func->flags & FUNC_HAS_PS0) { 610 if (func->flags & FUNC_HAS_PS0) {
808 dbg("%s: executing _PS0\n", __func__); 611 dbg("%s: executing _PS0\n", __func__);
809 status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); 612 status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL);
@@ -829,7 +632,6 @@ static int power_off_slot(struct acpiphp_slot *slot)
829{ 632{
830 acpi_status status; 633 acpi_status status;
831 struct acpiphp_func *func; 634 struct acpiphp_func *func;
832 struct list_head *l;
833 635
834 int retval = 0; 636 int retval = 0;
835 637
@@ -837,9 +639,7 @@ static int power_off_slot(struct acpiphp_slot *slot)
837 if ((slot->flags & SLOT_POWEREDON) == 0) 639 if ((slot->flags & SLOT_POWEREDON) == 0)
838 goto err_exit; 640 goto err_exit;
839 641
840 list_for_each (l, &slot->funcs) { 642 list_for_each_entry(func, &slot->funcs, sibling) {
841 func = list_entry(l, struct acpiphp_func, sibling);
842
843 if (func->flags & FUNC_HAS_PS3) { 643 if (func->flags & FUNC_HAS_PS3) {
844 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); 644 status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL);
845 if (ACPI_FAILURE(status)) { 645 if (ACPI_FAILURE(status)) {
@@ -966,7 +766,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
966{ 766{
967 struct pci_dev *dev; 767 struct pci_dev *dev;
968 struct pci_bus *bus = slot->bridge->pci_bus; 768 struct pci_bus *bus = slot->bridge->pci_bus;
969 struct list_head *l;
970 struct acpiphp_func *func; 769 struct acpiphp_func *func;
971 int retval = 0; 770 int retval = 0;
972 int num, max, pass; 771 int num, max, pass;
@@ -1006,21 +805,16 @@ static int __ref enable_device(struct acpiphp_slot *slot)
1006 } 805 }
1007 } 806 }
1008 807
1009 list_for_each (l, &slot->funcs) { 808 list_for_each_entry(func, &slot->funcs, sibling)
1010 func = list_entry(l, struct acpiphp_func, sibling);
1011 acpiphp_bus_add(func); 809 acpiphp_bus_add(func);
1012 }
1013 810
1014 pci_bus_assign_resources(bus); 811 pci_bus_assign_resources(bus);
1015 acpiphp_sanitize_bus(bus); 812 acpiphp_sanitize_bus(bus);
1016 acpiphp_set_hpp_values(bus); 813 acpiphp_set_hpp_values(bus);
1017 list_for_each_entry(func, &slot->funcs, sibling)
1018 acpiphp_configure_ioapics(func->handle);
1019 pci_enable_bridges(bus); 814 pci_enable_bridges(bus);
1020 pci_bus_add_devices(bus); 815 pci_bus_add_devices(bus);
1021 816
1022 list_for_each (l, &slot->funcs) { 817 list_for_each_entry(func, &slot->funcs, sibling) {
1023 func = list_entry(l, struct acpiphp_func, sibling);
1024 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 818 dev = pci_get_slot(bus, PCI_DEVFN(slot->device,
1025 func->function)); 819 func->function));
1026 if (!dev) 820 if (!dev)
@@ -1091,7 +885,6 @@ static int disable_device(struct acpiphp_slot *slot)
1091 } 885 }
1092 886
1093 list_for_each_entry(func, &slot->funcs, sibling) { 887 list_for_each_entry(func, &slot->funcs, sibling) {
1094 acpiphp_unconfigure_ioapics(func->handle);
1095 acpiphp_bus_trim(func->handle); 888 acpiphp_bus_trim(func->handle);
1096 } 889 }
1097 890
@@ -1119,12 +912,9 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot)
1119 acpi_status status; 912 acpi_status status;
1120 unsigned long long sta = 0; 913 unsigned long long sta = 0;
1121 u32 dvid; 914 u32 dvid;
1122 struct list_head *l;
1123 struct acpiphp_func *func; 915 struct acpiphp_func *func;
1124 916
1125 list_for_each (l, &slot->funcs) { 917 list_for_each_entry(func, &slot->funcs, sibling) {
1126 func = list_entry(l, struct acpiphp_func, sibling);
1127
1128 if (func->flags & FUNC_HAS_STA) { 918 if (func->flags & FUNC_HAS_STA) {
1129 status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); 919 status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta);
1130 if (ACPI_SUCCESS(status) && sta) 920 if (ACPI_SUCCESS(status) && sta)
@@ -1152,13 +942,10 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot)
1152{ 942{
1153 acpi_status status; 943 acpi_status status;
1154 struct acpiphp_func *func; 944 struct acpiphp_func *func;
1155 struct list_head *l;
1156 struct acpi_object_list arg_list; 945 struct acpi_object_list arg_list;
1157 union acpi_object arg; 946 union acpi_object arg;
1158 947
1159 list_for_each (l, &slot->funcs) { 948 list_for_each_entry(func, &slot->funcs, sibling) {
1160 func = list_entry(l, struct acpiphp_func, sibling);
1161
1162 /* We don't want to call _EJ0 on non-existing functions. */ 949 /* We don't want to call _EJ0 on non-existing functions. */
1163 if ((func->flags & FUNC_HAS_EJ0)) { 950 if ((func->flags & FUNC_HAS_EJ0)) {
1164 /* _EJ0 method take one argument */ 951 /* _EJ0 method take one argument */
@@ -1275,7 +1062,6 @@ static int acpiphp_configure_bridge (acpi_handle handle)
1275 acpiphp_sanitize_bus(bus); 1062 acpiphp_sanitize_bus(bus);
1276 acpiphp_set_hpp_values(bus); 1063 acpiphp_set_hpp_values(bus);
1277 pci_enable_bridges(bus); 1064 pci_enable_bridges(bus);
1278 acpiphp_configure_ioapics(handle);
1279 return 0; 1065 return 0;
1280} 1066}
1281 1067
@@ -1542,7 +1328,7 @@ int __init acpiphp_get_num_slots(void)
1542 struct acpiphp_bridge *bridge; 1328 struct acpiphp_bridge *bridge;
1543 int num_slots = 0; 1329 int num_slots = 0;
1544 1330
1545 list_for_each_entry (bridge, &bridge_list, list) { 1331 list_for_each_entry(bridge, &bridge_list, list) {
1546 dbg("Bus %04x:%02x has %d slot%s\n", 1332 dbg("Bus %04x:%02x has %d slot%s\n",
1547 pci_domain_nr(bridge->pci_bus), 1333 pci_domain_nr(bridge->pci_bus),
1548 bridge->pci_bus->number, bridge->nr_slots, 1334 bridge->pci_bus->number, bridge->nr_slots,