diff options
author | Rafael J. Wysocki | 2013-08-27 01:26:37 +0200 |
---|---|---|
committer | Rafael J. Wysocki | 2013-08-27 01:26:37 +0200 |
commit | abe5430e9d5314190ca571b3bfc0c42000634378 (patch) | |
tree | b78f767e96d5a99d6440bfdfdb99d6b7acfae500 /drivers/acpi | |
parent | c92f56cbdfc08c8c207c9476c69c99fdbadbd77b (diff) | |
parent | ad07277e82dedabacc52c82746633680a3187d25 (diff) |
Merge branch 'acpi-pci-hotplug'
* acpi-pci-hotplug: (34 commits)
ACPI / PM: Hold acpi_scan_lock over system PM transitions
ACPI / hotplug / PCI: Fix NULL pointer dereference in cleanup_bridge()
PCI / ACPI: Use dev_dbg() instead of dev_info() in acpi_pci_set_power_state()
ACPI / hotplug / PCI: Get rid of check_sub_bridges()
ACPI / hotplug / PCI: Clean up bridge_mutex usage
ACPI / hotplug / PCI: Redefine enable_device() and disable_device()
ACPI / hotplug / PCI: Sanitize acpiphp_get_(latch)|(adapter)_status()
ACPI / hotplug / PCI: Get rid of unused constants in acpiphp.h
ACPI / hotplug / PCI: Check for new devices on enabled slots
ACPI / hotplug / PCI: Allow slots without new devices to be rescanned
ACPI / hotplug / PCI: Do not check SLOT_ENABLED in enable_device()
ACPI / hotplug / PCI: Do not exectute _PS0 and _PS3 directly
ACPI / hotplug / PCI: Do not queue up event handling work items in vain
ACPI / hotplug / PCI: Consolidate slot disabling and ejecting
ACPI / hotplug / PCI: Drop redundant checks from check_hotplug_bridge()
ACPI / hotplug / PCI: Rework namespace scanning and trimming routines
ACPI / hotplug / PCI: Store parent in functions and bus in slots
ACPI / hotplug / PCI: Drop handle field from struct acpiphp_bridge
ACPI / hotplug / PCI: Drop handle field from struct acpiphp_func
ACPI / hotplug / PCI: Embed function struct into struct acpiphp_context
...
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/pci_slot.c | 14 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 39 |
2 files changed, 33 insertions, 20 deletions
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 033d1179bdb5..d678a180ca2a 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -159,12 +159,16 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } -void acpi_pci_slot_enumerate(struct pci_bus *bus, acpi_handle handle) +void acpi_pci_slot_enumerate(struct pci_bus *bus) { - mutex_lock(&slot_list_lock); - acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, - register_slot, NULL, bus, NULL); - mutex_unlock(&slot_list_lock); + acpi_handle handle = ACPI_HANDLE(bus->bridge); + + if (handle) { + mutex_lock(&slot_list_lock); + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, + register_slot, NULL, bus, NULL); + mutex_unlock(&slot_list_lock); + } } void acpi_pci_slot_remove(struct pci_bus *bus) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 81b0f03d97db..1dec53decffa 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -420,10 +420,21 @@ static void acpi_pm_finish(void) } /** - * acpi_pm_end - Finish up suspend sequence. + * acpi_pm_start - Start system PM transition. + */ +static void acpi_pm_start(u32 acpi_state) +{ + acpi_target_sleep_state = acpi_state; + acpi_sleep_tts_switch(acpi_target_sleep_state); + acpi_scan_lock_acquire(); +} + +/** + * acpi_pm_end - Finish up system PM transition. */ static void acpi_pm_end(void) { + acpi_scan_lock_release(); /* * This is necessary in case acpi_pm_finish() is not called during a * failing transition to a sleep state. @@ -451,21 +462,19 @@ static u32 acpi_suspend_states[] = { static int acpi_suspend_begin(suspend_state_t pm_state) { u32 acpi_state = acpi_suspend_states[pm_state]; - int error = 0; + int error; error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); if (error) return error; - if (sleep_states[acpi_state]) { - acpi_target_sleep_state = acpi_state; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } else { - printk(KERN_ERR "ACPI does not support this state: %d\n", - pm_state); - error = -ENOSYS; + if (!sleep_states[acpi_state]) { + pr_err("ACPI does not support sleep state S%u\n", acpi_state); + return -ENOSYS; } - return error; + + acpi_pm_start(acpi_state); + return 0; } /** @@ -631,10 +640,8 @@ static int acpi_hibernation_begin(void) int error; error = nvs_nosave ? 0 : suspend_nvs_alloc(); - if (!error) { - acpi_target_sleep_state = ACPI_STATE_S4; - acpi_sleep_tts_switch(acpi_target_sleep_state); - } + if (!error) + acpi_pm_start(ACPI_STATE_S4); return error; } @@ -713,8 +720,10 @@ static int acpi_hibernation_begin_old(void) if (!error) { if (!nvs_nosave) error = suspend_nvs_alloc(); - if (!error) + if (!error) { acpi_target_sleep_state = ACPI_STATE_S4; + acpi_scan_lock_acquire(); + } } return error; } |