aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/osl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r--drivers/acpi/osl.c159
1 files changed, 112 insertions, 47 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 13b5fd5854a8..1bb558adee66 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -37,6 +37,7 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39#include <linux/nmi.h> 39#include <linux/nmi.h>
40#include <linux/kthread.h>
40#include <acpi/acpi.h> 41#include <acpi/acpi.h>
41#include <asm/io.h> 42#include <asm/io.h>
42#include <acpi/acpi_bus.h> 43#include <acpi/acpi_bus.h>
@@ -600,23 +601,41 @@ static void acpi_os_execute_deferred(void *context)
600 return_VOID; 601 return_VOID;
601} 602}
602 603
603acpi_status 604static int acpi_os_execute_thread(void *context)
604acpi_os_queue_for_execution(u32 priority, 605{
606 struct acpi_os_dpc *dpc = (struct acpi_os_dpc *)context;
607 if (dpc) {
608 dpc->function(dpc->context);
609 kfree(dpc);
610 }
611 do_exit(0);
612}
613
614/*******************************************************************************
615 *
616 * FUNCTION: acpi_os_execute
617 *
618 * PARAMETERS: Type - Type of the callback
619 * Function - Function to be executed
620 * Context - Function parameters
621 *
622 * RETURN: Status
623 *
624 * DESCRIPTION: Depending on type, either queues function for deferred execution or
625 * immediately executes function on a separate thread.
626 *
627 ******************************************************************************/
628
629acpi_status acpi_os_execute(acpi_execute_type type,
605 acpi_osd_exec_callback function, void *context) 630 acpi_osd_exec_callback function, void *context)
606{ 631{
607 acpi_status status = AE_OK; 632 acpi_status status = AE_OK;
608 struct acpi_os_dpc *dpc; 633 struct acpi_os_dpc *dpc;
609 struct work_struct *task; 634 struct work_struct *task;
610 635 struct task_struct *p;
611 ACPI_FUNCTION_TRACE("os_queue_for_execution");
612
613 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
614 "Scheduling function [%p(%p)] for deferred execution.\n",
615 function, context));
616 636
617 if (!function) 637 if (!function)
618 return_ACPI_STATUS(AE_BAD_PARAMETER); 638 return AE_BAD_PARAMETER;
619
620 /* 639 /*
621 * Allocate/initialize DPC structure. Note that this memory will be 640 * Allocate/initialize DPC structure. Note that this memory will be
622 * freed by the callee. The kernel handles the tq_struct list in a 641 * freed by the callee. The kernel handles the tq_struct list in a
@@ -627,30 +646,37 @@ acpi_os_queue_for_execution(u32 priority,
627 * We can save time and code by allocating the DPC and tq_structs 646 * We can save time and code by allocating the DPC and tq_structs
628 * from the same memory. 647 * from the same memory.
629 */ 648 */
630 649 if (type == OSL_NOTIFY_HANDLER) {
631 dpc = 650 dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_KERNEL);
632 kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), 651 } else {
633 GFP_ATOMIC); 652 dpc = kmalloc(sizeof(struct acpi_os_dpc) +
653 sizeof(struct work_struct), GFP_ATOMIC);
654 }
634 if (!dpc) 655 if (!dpc)
635 return_ACPI_STATUS(AE_NO_MEMORY); 656 return AE_NO_MEMORY;
636
637 dpc->function = function; 657 dpc->function = function;
638 dpc->context = context; 658 dpc->context = context;
639 659
640 task = (void *)(dpc + 1); 660 if (type == OSL_NOTIFY_HANDLER) {
641 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); 661 p = kthread_create(acpi_os_execute_thread, dpc, "kacpid_notify");
642 662 if (!IS_ERR(p)) {
643 if (!queue_work(kacpid_wq, task)) { 663 wake_up_process(p);
644 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 664 } else {
645 "Call to queue_work() failed.\n")); 665 status = AE_NO_MEMORY;
646 kfree(dpc); 666 kfree(dpc);
647 status = AE_ERROR; 667 }
668 } else {
669 task = (void *)(dpc + 1);
670 INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc);
671 if (!queue_work(kacpid_wq, task)) {
672 status = AE_ERROR;
673 kfree(dpc);
674 }
648 } 675 }
649 676 return status;
650 return_ACPI_STATUS(status);
651} 677}
652 678
653EXPORT_SYMBOL(acpi_os_queue_for_execution); 679EXPORT_SYMBOL(acpi_os_execute);
654 680
655void acpi_os_wait_events_complete(void *context) 681void acpi_os_wait_events_complete(void *context)
656{ 682{
@@ -769,9 +795,6 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
769 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", 795 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n",
770 handle, units, timeout)); 796 handle, units, timeout));
771 797
772 if (in_atomic())
773 timeout = 0;
774
775 switch (timeout) { 798 switch (timeout) {
776 /* 799 /*
777 * No Wait: 800 * No Wait:
@@ -896,14 +919,6 @@ u8 acpi_os_writable(void *ptr, acpi_size len)
896} 919}
897#endif 920#endif
898 921
899u32 acpi_os_get_thread_id(void)
900{
901 if (!in_atomic())
902 return current->pid;
903
904 return 0;
905}
906
907acpi_status acpi_os_signal(u32 function, void *info) 922acpi_status acpi_os_signal(u32 function, void *info)
908{ 923{
909 switch (function) { 924 switch (function) {
@@ -1050,12 +1065,12 @@ void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags)
1050 * 1065 *
1051 * FUNCTION: acpi_os_create_cache 1066 * FUNCTION: acpi_os_create_cache
1052 * 1067 *
1053 * PARAMETERS: CacheName - Ascii name for the cache 1068 * PARAMETERS: name - Ascii name for the cache
1054 * ObjectSize - Size of each cached object 1069 * size - Size of each cached object
1055 * MaxDepth - Maximum depth of the cache (in objects) 1070 * depth - Maximum depth of the cache (in objects) <ignored>
1056 * ReturnCache - Where the new cache object is returned 1071 * cache - Where the new cache object is returned
1057 * 1072 *
1058 * RETURN: Status 1073 * RETURN: status
1059 * 1074 *
1060 * DESCRIPTION: Create a cache object 1075 * DESCRIPTION: Create a cache object
1061 * 1076 *
@@ -1065,7 +1080,10 @@ acpi_status
1065acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) 1080acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
1066{ 1081{
1067 *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); 1082 *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL);
1068 return AE_OK; 1083 if (cache == NULL)
1084 return AE_ERROR;
1085 else
1086 return AE_OK;
1069} 1087}
1070 1088
1071/******************************************************************************* 1089/*******************************************************************************
@@ -1134,16 +1152,63 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1134 * 1152 *
1135 * RETURN: Status 1153 * RETURN: Status
1136 * 1154 *
1137 * DESCRIPTION: Get an object from the specified cache. If cache is empty, 1155 * DESCRIPTION: Return a zero-filled object.
1138 * the object is allocated.
1139 * 1156 *
1140 ******************************************************************************/ 1157 ******************************************************************************/
1141 1158
1142void *acpi_os_acquire_object(acpi_cache_t * cache) 1159void *acpi_os_acquire_object(acpi_cache_t * cache)
1143{ 1160{
1144 void *object = kmem_cache_alloc(cache, GFP_KERNEL); 1161 void *object = kmem_cache_zalloc(cache, GFP_KERNEL);
1145 WARN_ON(!object); 1162 WARN_ON(!object);
1146 return object; 1163 return object;
1147} 1164}
1148 1165
1166/******************************************************************************
1167 *
1168 * FUNCTION: acpi_os_validate_interface
1169 *
1170 * PARAMETERS: interface - Requested interface to be validated
1171 *
1172 * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise
1173 *
1174 * DESCRIPTION: Match an interface string to the interfaces supported by the
1175 * host. Strings originate from an AML call to the _OSI method.
1176 *
1177 *****************************************************************************/
1178
1179acpi_status
1180acpi_os_validate_interface (char *interface)
1181{
1182
1183 return AE_SUPPORT;
1184}
1185
1186
1187/******************************************************************************
1188 *
1189 * FUNCTION: acpi_os_validate_address
1190 *
1191 * PARAMETERS: space_id - ACPI space ID
1192 * address - Physical address
1193 * length - Address length
1194 *
1195 * RETURN: AE_OK if address/length is valid for the space_id. Otherwise,
1196 * should return AE_AML_ILLEGAL_ADDRESS.
1197 *
1198 * DESCRIPTION: Validate a system address via the host OS. Used to validate
1199 * the addresses accessed by AML operation regions.
1200 *
1201 *****************************************************************************/
1202
1203acpi_status
1204acpi_os_validate_address (
1205 u8 space_id,
1206 acpi_physical_address address,
1207 acpi_size length)
1208{
1209
1210 return AE_OK;
1211}
1212
1213
1149#endif 1214#endif