diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 30 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 21 | ||||
-rw-r--r-- | drivers/pci/pci.c | 8 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 4 |
4 files changed, 46 insertions, 17 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 641ba6761bd7..ee26bac2d378 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -279,7 +279,9 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); if (ACPI_FAILURE(status)) { - acpi_handle_warn(handle, "can't evaluate _ADR (%#x)\n", status); + if (status != AE_NOT_FOUND) + acpi_handle_warn(handle, + "can't evaluate _ADR (%#x)\n", status); return AE_OK; } @@ -646,6 +648,24 @@ static void disable_slot(struct acpiphp_slot *slot) slot->flags &= (~SLOT_ENABLED); } +static bool acpiphp_no_hotplug(acpi_handle handle) +{ + struct acpi_device *adev = NULL; + + acpi_bus_get_device(handle, &adev); + return adev && adev->flags.no_hotplug; +} + +static bool slot_no_hotplug(struct acpiphp_slot *slot) +{ + struct acpiphp_func *func; + + list_for_each_entry(func, &slot->funcs, sibling) + if (acpiphp_no_hotplug(func_to_handle(func))) + return true; + + return false; +} /** * get_slot_status - get ACPI slot status @@ -704,7 +724,8 @@ static void trim_stale_devices(struct pci_dev *dev) unsigned long long sta; status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - alive = ACPI_SUCCESS(status) && sta == ACPI_STA_ALL; + alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL) + || acpiphp_no_hotplug(handle); } if (!alive) { u32 v; @@ -748,8 +769,9 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge) struct pci_dev *dev, *tmp; mutex_lock(&slot->crit_sect); - /* wake up all functions */ - if (get_slot_status(slot) == ACPI_STA_ALL) { + if (slot_no_hotplug(slot)) { + ; /* do nothing */ + } else if (get_slot_status(slot) == ACPI_STA_ALL) { /* remove stale devices if any */ list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index e0431f1af33b..2bdbc0080204 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -330,29 +330,32 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) static void pci_acpi_setup(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - acpi_handle handle = ACPI_HANDLE(dev); - struct acpi_device *adev; + struct acpi_device *adev = ACPI_COMPANION(dev); - if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) + if (!adev) + return; + + pci_acpi_add_pm_notifier(adev, pci_dev); + if (!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) { - acpi_handle handle = ACPI_HANDLE(dev); - struct acpi_device *adev; + struct acpi_device *adev = ACPI_COMPANION(dev); + + if (!adev) + return; - if (!acpi_bus_get_device(handle, &adev) && adev->wakeup.flags.valid) { + pci_acpi_remove_pm_notifier(adev); + if (adev->wakeup.flags.valid) { device_set_wakeup_capable(dev, false); device_set_run_wake(dev, false); - pci_acpi_remove_pm_notifier(adev); } } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index b6d4afa8ba40..1febe90831b4 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -4125,6 +4125,14 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, return 0; } +bool pci_device_is_present(struct pci_dev *pdev) +{ + u32 v; + + return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0); +} +EXPORT_SYMBOL_GPL(pci_device_is_present); + #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; static DEFINE_SPINLOCK(resource_alignment_lock); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 4ad6bf6c107b..5cb726c193de 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -9,10 +9,6 @@ * * Init/reset quirks for USB host controllers should be in the * USB quirks file, where their drivers can access reuse it. - * - * The bridge optimization stuff has been removed. If you really - * have a silly BIOS which is unable to set your host bridge right, - * use the PowerTweak utility (see http://powertweak.sourceforge.net). */ #include <linux/types.h> |