Merge branch 'wakeup-etc-rafael' into release
This commit is contained in:
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context)
|
|||||||
* RETURN: ACPI_INTERRUPT_HANDLED
|
* RETURN: ACPI_INTERRUPT_HANDLED
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
|
* DESCRIPTION: Invoked directly from the SCI handler when a global lock
|
||||||
* release interrupt occurs. Attempt to acquire the global lock,
|
* release interrupt occurs. If there's a thread waiting for
|
||||||
* if successful, signal the thread waiting for the lock.
|
* the global lock, signal it.
|
||||||
*
|
*
|
||||||
* NOTE: Assumes that the semaphore can be signaled from interrupt level. If
|
* 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
|
* this is not possible for some reason, a separate thread will have to be
|
||||||
* scheduled to do this.
|
* 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)
|
static u32 acpi_ev_global_lock_handler(void *context)
|
||||||
{
|
{
|
||||||
u8 acquired = FALSE;
|
acpi_status status;
|
||||||
|
acpi_cpu_flags flags;
|
||||||
|
|
||||||
/*
|
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
|
||||||
* 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) {
|
|
||||||
|
|
||||||
/* 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"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send a unit to the 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);
|
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_status acpi_ev_acquire_global_lock(u16 timeout)
|
||||||
{
|
{
|
||||||
|
acpi_cpu_flags flags;
|
||||||
acpi_status status = AE_OK;
|
acpi_status status = AE_OK;
|
||||||
u8 acquired = FALSE;
|
u8 acquired = FALSE;
|
||||||
|
|
||||||
@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout)
|
|||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to acquire the actual hardware lock */
|
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
|
||||||
|
|
||||||
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
|
do {
|
||||||
if (acquired) {
|
|
||||||
|
|
||||||
/* We got the lock */
|
/* Attempt to acquire the actual hardware lock */
|
||||||
|
|
||||||
|
ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
|
||||||
|
if (acquired) {
|
||||||
|
acpi_gbl_global_lock_acquired = TRUE;
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||||
|
"Acquired hardware Global Lock\n"));
|
||||||
|
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 wait until we get the global lock released interrupt.
|
||||||
|
*/
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||||
"Acquired hardware Global Lock\n"));
|
"Waiting for hardware Global Lock\n"));
|
||||||
|
|
||||||
acpi_gbl_global_lock_acquired = TRUE;
|
/*
|
||||||
return_ACPI_STATUS(AE_OK);
|
* 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,
|
||||||
|
ACPI_WAIT_FOREVER);
|
||||||
|
|
||||||
/*
|
flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
|
||||||
* Did not get the lock. The pending bit was set above, and we must now
|
|
||||||
* wait until we get the global lock released interrupt.
|
|
||||||
*/
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n"));
|
|
||||||
|
|
||||||
/*
|
} while (ACPI_SUCCESS(status));
|
||||||
* Wait for handshake with the global lock interrupt handler.
|
|
||||||
* This interface releases the interpreter if we must wait.
|
acpi_ev_global_lock_pending = FALSE;
|
||||||
*/
|
|
||||||
status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore,
|
acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
|
||||||
ACPI_WAIT_FOREVER);
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
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_report_switch(button->input, SW_LID, !state);
|
||||||
input_sync(button->input);
|
input_sync(button->input);
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
pm_wakeup_event(&device->dev, 0);
|
||||||
|
|
||||||
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
|
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
|
||||||
if (ret == NOTIFY_DONE)
|
if (ret == NOTIFY_DONE)
|
||||||
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
|
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_sync(input);
|
||||||
input_report_key(input, keycode, 0);
|
input_report_key(input, keycode, 0);
|
||||||
input_sync(input);
|
input_sync(input);
|
||||||
|
|
||||||
|
pm_wakeup_event(&device->dev, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_bus_generate_proc_event(device, event, ++button->pushed);
|
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,
|
acpi_enable_gpe(device->wakeup.gpe_device,
|
||||||
device->wakeup.gpe_number);
|
device->wakeup.gpe_number);
|
||||||
device->wakeup.run_wake_count++;
|
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));
|
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,
|
acpi_disable_gpe(device->wakeup.gpe_device,
|
||||||
device->wakeup.gpe_number);
|
device->wakeup.gpe_number);
|
||||||
device->wakeup.run_wake_count--;
|
device->wakeup.run_wake_count--;
|
||||||
device->wakeup.state.enabled = 0;
|
device_set_wakeup_enable(&device->dev, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
acpi_button_remove_fs(device);
|
acpi_button_remove_fs(device);
|
||||||
|
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
|
|||||||
"firmware_node");
|
"firmware_node");
|
||||||
ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
|
||||||
"physical_node");
|
"physical_node");
|
||||||
if (acpi_dev->wakeup.flags.valid) {
|
if (acpi_dev->wakeup.flags.valid)
|
||||||
device_set_wakeup_capable(dev, true);
|
device_set_wakeup_capable(dev, true);
|
||||||
device_set_wakeup_enable(dev,
|
|
||||||
acpi_dev->wakeup.state.enabled);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset)
|
|||||||
dev->pnp.bus_id,
|
dev->pnp.bus_id,
|
||||||
(u32) dev->wakeup.sleep_state,
|
(u32) dev->wakeup.sleep_state,
|
||||||
dev->wakeup.flags.run_wake ? '*' : ' ',
|
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)
|
if (ldev)
|
||||||
seq_printf(seq, "%s:%s",
|
seq_printf(seq, "%s:%s",
|
||||||
ldev->bus ? ldev->bus->name : "no-bus",
|
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);
|
struct device *dev = acpi_get_physical_device(adev->handle);
|
||||||
|
|
||||||
if (dev && device_can_wakeup(dev))
|
if (dev && device_can_wakeup(dev)) {
|
||||||
device_set_wakeup_enable(dev, adev->wakeup.state.enabled);
|
bool enable = !device_may_wakeup(dev);
|
||||||
|
device_set_wakeup_enable(dev, enable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file,
|
|||||||
char strbuf[5];
|
char strbuf[5];
|
||||||
char str[5] = "";
|
char str[5] = "";
|
||||||
unsigned int len = count;
|
unsigned int len = count;
|
||||||
struct acpi_device *found_dev = NULL;
|
|
||||||
|
|
||||||
if (len > 4)
|
if (len > 4)
|
||||||
len = 4;
|
len = 4;
|
||||||
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!strncmp(dev->pnp.bus_id, str, 4)) {
|
if (!strncmp(dev->pnp.bus_id, str, 4)) {
|
||||||
dev->wakeup.state.enabled =
|
if (device_can_wakeup(&dev->dev)) {
|
||||||
dev->wakeup.state.enabled ? 0 : 1;
|
bool enable = !device_may_wakeup(&dev->dev);
|
||||||
found_dev = dev;
|
device_set_wakeup_enable(&dev->dev, enable);
|
||||||
break;
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
physical_device_enable_wakeup(dev);
|
physical_device_enable_wakeup(dev);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&acpi_device_lock);
|
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 */
|
/* Power button, Lid switch always enable wakeup */
|
||||||
if (!acpi_match_device_ids(device, button_device_ids)) {
|
if (!acpi_match_device_ids(device, button_device_ids)) {
|
||||||
device->wakeup.flags.run_wake = 1;
|
device->wakeup.flags.run_wake = 1;
|
||||||
device->wakeup.flags.always_enabled = 1;
|
device_set_wakeup_capable(&device->dev, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -435,6 +435,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
|
|||||||
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
|
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 */
|
#endif /* CONFIG_SUSPEND */
|
||||||
|
@@ -37,11 +37,12 @@ void acpi_enable_wakeup_devices(u8 sleep_state)
|
|||||||
container_of(node, struct acpi_device, wakeup_list);
|
container_of(node, struct acpi_device, wakeup_list);
|
||||||
|
|
||||||
if (!dev->wakeup.flags.valid
|
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;
|
continue;
|
||||||
|
|
||||||
if (dev->wakeup.state.enabled)
|
if (device_may_wakeup(&dev->dev))
|
||||||
acpi_enable_wakeup_device_power(dev, sleep_state);
|
acpi_enable_wakeup_device_power(dev, sleep_state);
|
||||||
|
|
||||||
/* The wake-up power should have been enabled already. */
|
/* 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);
|
container_of(node, struct acpi_device, wakeup_list);
|
||||||
|
|
||||||
if (!dev->wakeup.flags.valid
|
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;
|
continue;
|
||||||
|
|
||||||
acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
|
acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number,
|
||||||
ACPI_GPE_DISABLE);
|
ACPI_GPE_DISABLE);
|
||||||
|
|
||||||
if (dev->wakeup.state.enabled)
|
if (device_may_wakeup(&dev->dev))
|
||||||
acpi_disable_wakeup_device_power(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 *dev = container_of(node,
|
||||||
struct acpi_device,
|
struct acpi_device,
|
||||||
wakeup_list);
|
wakeup_list);
|
||||||
if (dev->wakeup.flags.always_enabled)
|
if (device_can_wakeup(&dev->dev))
|
||||||
dev->wakeup.state.enabled = 1;
|
device_set_wakeup_enable(&dev->dev, true);
|
||||||
}
|
}
|
||||||
mutex_unlock(&acpi_device_lock);
|
mutex_unlock(&acpi_device_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -241,20 +241,14 @@ struct acpi_device_perf {
|
|||||||
struct acpi_device_wakeup_flags {
|
struct acpi_device_wakeup_flags {
|
||||||
u8 valid:1; /* Can successfully enable wakeup? */
|
u8 valid:1; /* Can successfully enable wakeup? */
|
||||||
u8 run_wake:1; /* Run-Wake GPE devices */
|
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 */
|
u8 notifier_present:1; /* Wake-up notify handler has been installed */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acpi_device_wakeup_state {
|
|
||||||
u8 enabled:1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct acpi_device_wakeup {
|
struct acpi_device_wakeup {
|
||||||
acpi_handle gpe_device;
|
acpi_handle gpe_device;
|
||||||
u64 gpe_number;
|
u64 gpe_number;
|
||||||
u64 sleep_state;
|
u64 sleep_state;
|
||||||
struct acpi_handle_list resources;
|
struct acpi_handle_list resources;
|
||||||
struct acpi_device_wakeup_state state;
|
|
||||||
struct acpi_device_wakeup_flags flags;
|
struct acpi_device_wakeup_flags flags;
|
||||||
int prepare_count;
|
int prepare_count;
|
||||||
int run_wake_count;
|
int run_wake_count;
|
||||||
|
Reference in New Issue
Block a user