Commit fb4af417 authored by Len Brown's avatar Len Brown

Merge branch 'wakeup-etc-rafael' into release

parents 07bf2805 7b330707
......@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
* RETURN: ACPI_INTERRUPT_HANDLED
*
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
* release interrupt occurs. Attempt to acquire the global lock,
* if successful, signal the thread waiting for the lock.
* release interrupt occurs. If there's a thread waiting for
* the global lock, signal it.
*
* NOTE: Assumes that the semaphore can be signaled from interrupt level. If
* this is not possible for some reason, a separate thread will have to be
* scheduled to do this.
*
******************************************************************************/
static u8 acpi_ev_global_lock_pending;
static spinlock_t _acpi_ev_global_lock_pending_lock;
#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
static u32 acpi_ev_global_lock_handler(void *context)
{
u8 acquired = FALSE;
acpi_status status;
acpi_cpu_flags flags;
/*
* Attempt to get the lock.
*
* If we don't get it now, it will be marked pending and we will
* take another interrupt when it becomes free.
*/
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
/* Got the lock, now wake all threads waiting for it */
if (!acpi_ev_global_lock_pending) {
goto out;
}
acpi_gbl_global_lock_acquired = TRUE;
/* Send a unit to the semaphore */
if (ACPI_FAILURE
(acpi_os_signal_semaphore
(acpi_gbl_global_lock_semaphore, 1))) {
ACPI_ERROR((AE_INFO,
"Could not signal Global Lock semaphore"));
}
status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
}
acpi_ev_global_lock_pending = FALSE;
out:
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
return (ACPI_INTERRUPT_HANDLED);
}
......@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired;
acpi_status acpi_ev_acquire_global_lock(u16 timeout)
{
acpi_cpu_flags flags;
acpi_status status = AE_OK;
u8 acquired = FALSE;
......@@ -467,33 +468,48 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
return_ACPI_STATUS(AE_OK);
}
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
do {
/* Attempt to acquire the actual hardware lock */
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
if (acquired) {
/* We got the lock */
acpi_gbl_global_lock_acquired = TRUE;
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Acquired hardware Global Lock\n"));
acpi_gbl_global_lock_acquired = TRUE;
return_ACPI_STATUS(AE_OK);
break;
}
acpi_ev_global_lock_pending = TRUE;
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
/*
* Did not get the lock. The pending bit was set above, and we must now
* wait until we get the global lock released interrupt.
* Did not get the lock. The pending bit was set above, and we
* must wait until we get the global lock released interrupt.
*/
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Waiting for hardware Global Lock\n"));
/*
* Wait for handshake with the global lock interrupt handler.
* This interface releases the interpreter if we must wait.
*/
status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
status = acpi_ex_system_wait_semaphore(
acpi_gbl_global_lock_semaphore,
ACPI_WAIT_FOREVER);
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
} while (ACPI_SUCCESS(status));
acpi_ev_global_lock_pending = FALSE;
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
return_ACPI_STATUS(status);
}
......
......@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device)
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
if (state)
pm_wakeup_event(&device->dev, 0);
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
if (ret == NOTIFY_DONE)
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
......@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
pm_wakeup_event(&device->dev, 0);
}
acpi_bus_generate_proc_event(device, event, ++button->pushed);
......@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device)
acpi_enable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count++;
device->wakeup.state.enabled = 1;
device_set_wakeup_enable(&device->dev, true);
}
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
......@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type)
acpi_disable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
device->wakeup.run_wake_count--;
device->wakeup.state.enabled = 0;
device_set_wakeup_enable(&device->dev, false);
}
acpi_button_remove_fs(device);
......
......@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
"firmware_node");
ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
"physical_node");
if (acpi_dev->wakeup.flags.valid) {
if (acpi_dev->wakeup.flags.valid)
device_set_wakeup_capable(dev, true);
device_set_wakeup_enable(dev,
acpi_dev->wakeup.state.enabled);
}
}
return 0;
......
......@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
dev->pnp.bus_id,
(u32) dev->wakeup.sleep_state,
dev->wakeup.flags.run_wake ? '*' : ' ',
dev->wakeup.state.enabled ? "enabled" : "disabled");
(device_may_wakeup(&dev->dev)
|| (ldev && device_may_wakeup(ldev))) ?
"enabled" : "disabled");
if (ldev)
seq_printf(seq, "%s:%s",
ldev->bus ? ldev->bus->name : "no-bus",
......@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev)
{
struct device *dev = acpi_get_physical_device(adev->handle);
if (dev && device_can_wakeup(dev))
device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
if (dev && device_can_wakeup(dev)) {
bool enable = !device_may_wakeup(dev);
device_set_wakeup_enable(dev, enable);
}
}
static ssize_t
......@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
char strbuf[5];
char str[5] = "";
unsigned int len = count;
struct acpi_device *found_dev = NULL;
if (len > 4)
len = 4;
......@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
continue;
if (!strncmp(dev->pnp.bus_id, str, 4)) {
dev->wakeup.state.enabled =
dev->wakeup.state.enabled ? 0 : 1;
found_dev = dev;
break;
}
}
if (found_dev) {
physical_device_enable_wakeup(found_dev);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
struct
acpi_device,
wakeup_list);
if ((dev != found_dev) &&
(dev->wakeup.gpe_number ==
found_dev->wakeup.gpe_number)
&& (dev->wakeup.gpe_device ==
found_dev->wakeup.gpe_device)) {
printk(KERN_WARNING
"ACPI: '%s' and '%s' have the same GPE, "
"can't disable/enable one separately\n",
dev->pnp.bus_id, found_dev->pnp.bus_id);
dev->wakeup.state.enabled =
found_dev->wakeup.state.enabled;
if (device_can_wakeup(&dev->dev)) {
bool enable = !device_may_wakeup(&dev->dev);
device_set_wakeup_enable(&dev->dev, enable);
} else {
physical_device_enable_wakeup(dev);
}
break;
}
}
mutex_unlock(&acpi_device_lock);
......
......@@ -803,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
/* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) {
device->wakeup.flags.run_wake = 1;
device->wakeup.flags.always_enabled = 1;
device_set_wakeup_capable(&device->dev, true);
return;
}
......
......@@ -435,6 +435,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
},
},
{
.callback = init_nvs_nosave,
.ident = "Averatec AV1020-ED2",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
},
},
{},
};
#endif /* CONFIG_SUSPEND */
......
......@@ -37,11 +37,12 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid
|| !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
|| sleep_state > (u32) dev->wakeup.sleep_state)
|| sleep_state > (u32) dev->wakeup.sleep_state
|| !(device_may_wakeup(&dev->dev)
|| dev->wakeup.prepare_count))
continue;
if (dev->wakeup.state.enabled)
if (device_may_wakeup(&dev->dev))
acpi_enable_wakeup_device_power(dev, sleep_state);
/* The wake-up power should have been enabled already. */
......@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state)
container_of(node, struct acpi_device, wakeup_list);
if (!dev->wakeup.flags.valid
|| !(dev->wakeup.state.enabled || dev->wakeup.prepare_count)
|| (sleep_state > (u32) dev->wakeup.sleep_state))
|| sleep_state > (u32) dev->wakeup.sleep_state
|| !(device_may_wakeup(&dev->dev)
|| dev->wakeup.prepare_count))
continue;
acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
ACPI_GPE_DISABLE);
if (dev->wakeup.state.enabled)
if (device_may_wakeup(&dev->dev))
acpi_disable_wakeup_device_power(dev);
}
}
......@@ -84,8 +86,8 @@ int __init acpi_wakeup_device_init(void)
struct acpi_device *dev = container_of(node,
struct acpi_device,
wakeup_list);
if (dev->wakeup.flags.always_enabled)
dev->wakeup.state.enabled = 1;
if (device_can_wakeup(&dev->dev))
device_set_wakeup_enable(&dev->dev, true);
}
mutex_unlock(&acpi_device_lock);
return 0;
......
......@@ -241,20 +241,14 @@ struct acpi_device_perf {
struct acpi_device_wakeup_flags {
u8 valid:1; /* Can successfully enable wakeup? */
u8 run_wake:1; /* Run-Wake GPE devices */
u8 always_enabled:1; /* Run-wake devices that are always enabled */
u8 notifier_present:1; /* Wake-up notify handler has been installed */
};
struct acpi_device_wakeup_state {
u8 enabled:1;
};
struct acpi_device_wakeup {
acpi_handle gpe_device;
u64 gpe_number;
u64 sleep_state;
struct acpi_handle_list resources;
struct acpi_device_wakeup_state state;
struct acpi_device_wakeup_flags flags;
int prepare_count;
int run_wake_count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment