Pull bugfix into test branch
[linux-2.6.git] / drivers / acpi / osl.c
index e10679c..57ae1e5 100644 (file)
@@ -50,6 +50,7 @@ ACPI_MODULE_NAME("osl")
 struct acpi_os_dpc {
        acpi_osd_exec_callback function;
        void *context;
+       struct work_struct work;
 };
 
 #ifdef CONFIG_ACPI_CUSTOM_DSDT
@@ -73,7 +74,6 @@ static unsigned int acpi_irq_irq;
 static acpi_osd_handler acpi_irq_handler;
 static void *acpi_irq_context;
 static struct workqueue_struct *kacpid_wq;
-static struct workqueue_struct *kacpi_notify_wq;
 
 acpi_status acpi_os_initialize(void)
 {
@@ -92,9 +92,8 @@ acpi_status acpi_os_initialize1(void)
                return AE_NULL_ENTRY;
        }
        kacpid_wq = create_singlethread_workqueue("kacpid");
-       kacpi_notify_wq = create_singlethread_workqueue("kacpi_notify");
        BUG_ON(!kacpid_wq);
-       BUG_ON(!kacpi_notify_wq);
+
        return AE_OK;
 }
 
@@ -106,7 +105,6 @@ acpi_status acpi_os_terminate(void)
        }
 
        destroy_workqueue(kacpid_wq);
-       destroy_workqueue(kacpi_notify_wq);
 
        return AE_OK;
 }
@@ -567,9 +565,10 @@ void acpi_os_derive_pci_id(acpi_handle rhandle,    /* upper bound  */
        acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number);
 }
 
-static void acpi_os_execute_deferred(void *context)
+static void acpi_os_execute_deferred(struct work_struct *work)
 {
-       struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
+       struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
+
        if (!dpc) {
                printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
                return;
@@ -602,40 +601,41 @@ acpi_status acpi_os_execute(acpi_execute_type type,
 {
        acpi_status status = AE_OK;
        struct acpi_os_dpc *dpc;
-       struct work_struct *task;
+
+       ACPI_FUNCTION_TRACE("os_queue_for_execution");
 
        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                          "Scheduling function [%p(%p)] for deferred execution.\n",
                          function, context));
 
        if (!function)
-               return AE_BAD_PARAMETER;
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
 
        /*
         * Allocate/initialize DPC structure.  Note that this memory will be
-        * freed by the callee.  The kernel handles the tq_struct list  in a
+        * freed by the callee.  The kernel handles the work_struct list  in a
         * way that allows us to also free its memory inside the callee.
         * Because we may want to schedule several tasks with different
         * parameters we can't use the approach some kernel code uses of
-        * having a static tq_struct.
-        * We can save time and code by allocating the DPC and tq_structs
-        * from the same memory.
+        * having a static work_struct.
         */
 
-       dpc = kmalloc(sizeof(struct acpi_os_dpc) +
-                       sizeof(struct work_struct), GFP_ATOMIC);
+       dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
        if (!dpc)
-               return AE_NO_MEMORY;
+               return_ACPI_STATUS(AE_NO_MEMORY);
+
        dpc->function = function;
        dpc->context = context;
-       task = (void *)(dpc + 1);
-       INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
-       if (!queue_work((type == OSL_NOTIFY_HANDLER)?
-                       kacpi_notify_wq : kacpid_wq, task)) {
-               status = AE_ERROR;
+
+       INIT_WORK(&dpc->work, acpi_os_execute_deferred);
+       if (!queue_work(kacpid_wq, &dpc->work)) {
+               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+                                 "Call to queue_work() failed.\n"));
                kfree(dpc);
+               status = AE_ERROR;
        }
-       return status;
+
+       return_ACPI_STATUS(status);
 }
 
 EXPORT_SYMBOL(acpi_os_execute);
@@ -1052,7 +1052,7 @@ acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
 
 acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
 {
-       (void)kmem_cache_shrink(cache);
+       kmem_cache_shrink(cache);
        return (AE_OK);
 }