diff options
Diffstat (limited to 'drivers/pci/hotplug/pciehp_acpi.c')
| -rw-r--r-- | drivers/pci/hotplug/pciehp_acpi.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 96048010e7d..93cc9266e8c 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -26,6 +26,8 @@ #include <linux/acpi.h> #include <linux/pci.h> #include <linux/pci_hotplug.h> +#include <linux/slab.h> +#include <linux/module.h> #include "pciehp.h" #define PCIEHP_DETECT_PCIE (0) @@ -33,6 +35,11 @@ #define PCIEHP_DETECT_AUTO (2) #define PCIEHP_DETECT_DEFAULT PCIEHP_DETECT_AUTO +struct dummy_slot { + u32 number; + struct list_head list; +}; + static int slot_detection_mode; static char *pciehp_detect_mode; module_param(pciehp_detect_mode, charp, 0444); @@ -47,7 +54,7 @@ int pciehp_acpi_slot_detection_check(struct pci_dev *dev) { if (slot_detection_mode != PCIEHP_DETECT_ACPI) return 0; - if (acpi_pci_detect_ejectable(dev->subordinate)) + if (acpi_pci_detect_ejectable(ACPI_HANDLE(&dev->dev))) return 0; return -ENODEV; } @@ -71,48 +78,46 @@ static int __initdata dup_slot_id; static int __initdata acpi_slot_detected; static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); -/* Dummy driver for dumplicate name detection */ +/* Dummy driver for duplicate name detection */ static int __init dummy_probe(struct pcie_device *dev) { - int pos; u32 slot_cap; - struct slot *slot, *tmp; + acpi_handle handle; + struct dummy_slot *slot, *tmp; struct pci_dev *pdev = dev->port; - struct pci_bus *pbus = pdev->subordinate; - /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ - if (pciehp_get_hp_hw_control_from_firmware(pdev)) - return -ENODEV; - if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) - return -ENODEV; - pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); + + pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; - slot->number = slot_cap >> 19; - list_for_each_entry(tmp, &dummy_slots, slot_list) { + slot->number = (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19; + list_for_each_entry(tmp, &dummy_slots, list) { if (tmp->number == slot->number) dup_slot_id++; } - list_add_tail(&slot->slot_list, &dummy_slots); - if (!acpi_slot_detected && acpi_pci_detect_ejectable(pbus)) + list_add_tail(&slot->list, &dummy_slots); + handle = ACPI_HANDLE(&pdev->dev); + if (!acpi_slot_detected && acpi_pci_detect_ejectable(handle)) acpi_slot_detected = 1; return -ENODEV; /* dummy driver always returns error */ } static struct pcie_port_service_driver __initdata dummy_driver = { - .name = "pciehp_dummy", + .name = "pciehp_dummy", .port_type = PCIE_ANY_PORT, .service = PCIE_PORT_SERVICE_HP, - .probe = dummy_probe, + .probe = dummy_probe, }; static int __init select_detection_mode(void) { - struct slot *slot, *tmp; - pcie_port_service_register(&dummy_driver); + struct dummy_slot *slot, *tmp; + + if (pcie_port_service_register(&dummy_driver)) + return PCIEHP_DETECT_ACPI; pcie_port_service_unregister(&dummy_driver); - list_for_each_entry_safe(slot, tmp, &dummy_slots, slot_list) { - list_del(&slot->slot_list); + list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { + list_del(&slot->list); kfree(slot); } if (acpi_slot_detected && dup_slot_id) |
