|
@@ -682,6 +682,22 @@ static void acpi_os_execute_deferred(struct work_struct *work)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+static void acpi_os_execute_hp_deferred(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
|
|
|
+ if (!dpc) {
|
|
|
+ printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ acpi_os_wait_events_complete(NULL);
|
|
|
+
|
|
|
+ dpc->function(dpc->context);
|
|
|
+ kfree(dpc);
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* FUNCTION: acpi_os_execute
|
|
@@ -697,12 +713,13 @@ static void acpi_os_execute_deferred(struct work_struct *work)
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
|
|
|
-acpi_status acpi_os_execute(acpi_execute_type type,
|
|
|
- acpi_osd_exec_callback function, void *context)
|
|
|
+static acpi_status __acpi_os_execute(acpi_execute_type type,
|
|
|
+ acpi_osd_exec_callback function, void *context, int hp)
|
|
|
{
|
|
|
acpi_status status = AE_OK;
|
|
|
struct acpi_os_dpc *dpc;
|
|
|
struct workqueue_struct *queue;
|
|
|
+ int ret;
|
|
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
|
"Scheduling function [%p(%p)] for deferred execution.\n",
|
|
|
function, context));
|
|
@@ -726,9 +743,17 @@ acpi_status acpi_os_execute(acpi_execute_type type,
|
|
|
dpc->function = function;
|
|
|
dpc->context = context;
|
|
|
|
|
|
- INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
|
|
- queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq;
|
|
|
- if (!queue_work(queue, &dpc->work)) {
|
|
|
+ if (!hp) {
|
|
|
+ INIT_WORK(&dpc->work, acpi_os_execute_deferred);
|
|
|
+ queue = (type == OSL_NOTIFY_HANDLER) ?
|
|
|
+ kacpi_notify_wq : kacpid_wq;
|
|
|
+ ret = queue_work(queue, &dpc->work);
|
|
|
+ } else {
|
|
|
+ INIT_WORK(&dpc->work, acpi_os_execute_hp_deferred);
|
|
|
+ ret = schedule_work(&dpc->work);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!ret) {
|
|
|
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
|
|
"Call to queue_work() failed.\n"));
|
|
|
status = AE_ERROR;
|
|
@@ -737,8 +762,19 @@ acpi_status acpi_os_execute(acpi_execute_type type,
|
|
|
return_ACPI_STATUS(status);
|
|
|
}
|
|
|
|
|
|
+acpi_status acpi_os_execute(acpi_execute_type type,
|
|
|
+ acpi_osd_exec_callback function, void *context)
|
|
|
+{
|
|
|
+ return __acpi_os_execute(type, function, context, 0);
|
|
|
+}
|
|
|
EXPORT_SYMBOL(acpi_os_execute);
|
|
|
|
|
|
+acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
|
|
|
+ void *context)
|
|
|
+{
|
|
|
+ return __acpi_os_execute(0, function, context, 1);
|
|
|
+}
|
|
|
+
|
|
|
void acpi_os_wait_events_complete(void *context)
|
|
|
{
|
|
|
flush_workqueue(kacpid_wq);
|