X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fosl.c;fp=drivers%2Facpi%2Fosl.c;h=ac5bbaedac1ba7f15972881b1662081903ed2292;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=507f051d1cefd437634454809aa69c748f256a0d;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 507f051d1..ac5bbaeda 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -25,6 +25,7 @@ * */ +#include #include #include #include @@ -135,14 +136,32 @@ void acpi_os_vprintf(const char *fmt, va_list args) #endif } +extern int acpi_in_resume; +void *acpi_os_allocate(acpi_size size) +{ + if (acpi_in_resume) + return kmalloc(size, GFP_ATOMIC); + else + return kmalloc(size, GFP_KERNEL); +} + +void acpi_os_free(void *ptr) +{ + kfree(ptr); +} + +EXPORT_SYMBOL(acpi_os_free); + acpi_status acpi_os_get_root_pointer(u32 flags, struct acpi_pointer *addr) { if (efi_enabled) { addr->pointer_type = ACPI_PHYSICAL_POINTER; - if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) - addr->pointer.physical = efi.acpi20; - else if (efi.acpi != EFI_INVALID_TABLE_ADDR) - addr->pointer.physical = efi.acpi; + if (efi.acpi20) + addr->pointer.physical = + (acpi_physical_address) virt_to_phys(efi.acpi20); + else if (efi.acpi) + addr->pointer.physical = + (acpi_physical_address) virt_to_phys(efi.acpi); else { printk(KERN_ERR PREFIX "System description tables not found\n"); @@ -163,14 +182,22 @@ acpi_status acpi_os_map_memory(acpi_physical_address phys, acpi_size size, void __iomem ** virt) { - if (phys > ULONG_MAX) { - printk(KERN_ERR PREFIX "Cannot map memory that high\n"); - return AE_BAD_PARAMETER; + if (efi_enabled) { + if (EFI_MEMORY_WB & efi_mem_attributes(phys)) { + *virt = (void __iomem *)phys_to_virt(phys); + } else { + *virt = ioremap(phys, size); + } + } else { + if (phys > ULONG_MAX) { + printk(KERN_ERR PREFIX "Cannot map memory that high\n"); + return AE_BAD_PARAMETER; + } + /* + * ioremap checks to ensure this is in reserved space + */ + *virt = ioremap((unsigned long)phys, size); } - /* - * ioremap checks to ensure this is in reserved space - */ - *virt = ioremap((unsigned long)phys, size); if (!*virt) return AE_NO_MEMORY; @@ -262,7 +289,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, acpi_irq_handler = handler; acpi_irq_context = context; - if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { + if (request_irq(irq, acpi_irq, SA_SHIRQ, "acpi", acpi_irq)) { printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); return AE_NOT_ACQUIRED; } @@ -382,8 +409,18 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) { u32 dummy; void __iomem *virt_addr; + int iomem = 0; - virt_addr = ioremap(phys_addr, width); + if (efi_enabled) { + if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { + /* HACK ALERT! We can use readb/w/l on real memory too.. */ + virt_addr = (void __iomem *)phys_to_virt(phys_addr); + } else { + iomem = 1; + virt_addr = ioremap(phys_addr, width); + } + } else + virt_addr = (void __iomem *)phys_to_virt(phys_addr); if (!value) value = &dummy; @@ -401,7 +438,10 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) BUG(); } - iounmap(virt_addr); + if (efi_enabled) { + if (iomem) + iounmap(virt_addr); + } return AE_OK; } @@ -410,8 +450,18 @@ acpi_status acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) { void __iomem *virt_addr; + int iomem = 0; - virt_addr = ioremap(phys_addr, width); + if (efi_enabled) { + if (EFI_MEMORY_WB & efi_mem_attributes(phys_addr)) { + /* HACK ALERT! We can use writeb/w/l on real memory too */ + virt_addr = (void __iomem *)phys_to_virt(phys_addr); + } else { + iomem = 1; + virt_addr = ioremap(phys_addr, width); + } + } else + virt_addr = (void __iomem *)phys_to_virt(phys_addr); switch (width) { case 8: @@ -427,7 +477,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) BUG(); } - iounmap(virt_addr); + if (iomem) + iounmap(virt_addr); return AE_OK; } @@ -568,36 +619,23 @@ static void acpi_os_execute_deferred(void *context) { struct acpi_os_dpc *dpc = NULL; + ACPI_FUNCTION_TRACE("os_execute_deferred"); dpc = (struct acpi_os_dpc *)context; if (!dpc) { - printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); - return; + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); + return_VOID; } dpc->function(dpc->context); kfree(dpc); - return; + return_VOID; } -/******************************************************************************* - * - * FUNCTION: acpi_os_execute - * - * PARAMETERS: Type - Type of the callback - * Function - Function to be executed - * Context - Function parameters - * - * RETURN: Status - * - * DESCRIPTION: Depending on type, either queues function for deferred execution or - * immediately executes function on a separate thread. - * - ******************************************************************************/ - -acpi_status acpi_os_execute(acpi_execute_type type, +acpi_status +acpi_os_queue_for_execution(u32 priority, acpi_osd_exec_callback function, void *context) { acpi_status status = AE_OK; @@ -646,7 +684,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, return_ACPI_STATUS(status); } -EXPORT_SYMBOL(acpi_os_execute); +EXPORT_SYMBOL(acpi_os_queue_for_execution); void acpi_os_wait_events_complete(void *context) { @@ -658,19 +696,35 @@ EXPORT_SYMBOL(acpi_os_wait_events_complete); /* * Allocate the memory for a spinlock and initialize it. */ -acpi_status acpi_os_create_lock(acpi_spinlock * handle) +acpi_status acpi_os_create_lock(acpi_handle * out_handle) { - spin_lock_init(*handle); + spinlock_t *lock_ptr; - return AE_OK; + ACPI_FUNCTION_TRACE("os_create_lock"); + + lock_ptr = acpi_os_allocate(sizeof(spinlock_t)); + + spin_lock_init(lock_ptr); + + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating spinlock[%p].\n", lock_ptr)); + + *out_handle = lock_ptr; + + return_ACPI_STATUS(AE_OK); } /* * Deallocate the memory for a spinlock. */ -void acpi_os_delete_lock(acpi_spinlock handle) +void acpi_os_delete_lock(acpi_handle handle) { - return; + ACPI_FUNCTION_TRACE("os_create_lock"); + + ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting spinlock[%p].\n", handle)); + + acpi_os_free(handle); + + return_VOID; } acpi_status @@ -678,10 +732,11 @@ acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) { struct semaphore *sem = NULL; + ACPI_FUNCTION_TRACE("os_create_semaphore"); sem = acpi_os_allocate(sizeof(struct semaphore)); if (!sem) - return AE_NO_MEMORY; + return_ACPI_STATUS(AE_NO_MEMORY); memset(sem, 0, sizeof(struct semaphore)); sema_init(sem, initial_units); @@ -691,7 +746,7 @@ acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle) ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].\n", *handle, initial_units)); - return AE_OK; + return_ACPI_STATUS(AE_OK); } EXPORT_SYMBOL(acpi_os_create_semaphore); @@ -707,16 +762,17 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle) { struct semaphore *sem = (struct semaphore *)handle; + ACPI_FUNCTION_TRACE("os_delete_semaphore"); if (!sem) - return AE_BAD_PARAMETER; + return_ACPI_STATUS(AE_BAD_PARAMETER); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle)); - kfree(sem); + acpi_os_free(sem); sem = NULL; - return AE_OK; + return_ACPI_STATUS(AE_OK); } EXPORT_SYMBOL(acpi_os_delete_semaphore); @@ -736,25 +792,19 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) struct semaphore *sem = (struct semaphore *)handle; int ret = 0; + ACPI_FUNCTION_TRACE("os_wait_semaphore"); if (!sem || (units < 1)) - return AE_BAD_PARAMETER; + return_ACPI_STATUS(AE_BAD_PARAMETER); if (units > 1) - return AE_SUPPORT; + return_ACPI_STATUS(AE_SUPPORT); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); - /* - * This can be called during resume with interrupts off. - * Like boot-time, we should be single threaded and will - * always get the lock if we try -- timeout or not. - * If this doesn't succeed, then we will oops courtesy of - * might_sleep() in down(). - */ - if (!down_trylock(sem)) - return AE_OK; + if (in_atomic()) + timeout = 0; switch (timeout) { /* @@ -800,17 +850,17 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout) } if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Failed to acquire semaphore[%p|%d|%d], %s", + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Failed to acquire semaphore[%p|%d|%d], %s\n", handle, units, timeout, acpi_format_exception(status))); } else { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, - "Acquired semaphore[%p|%d|%d]", handle, + "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); } - return status; + return_ACPI_STATUS(status); } EXPORT_SYMBOL(acpi_os_wait_semaphore); @@ -822,19 +872,20 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units) { struct semaphore *sem = (struct semaphore *)handle; + ACPI_FUNCTION_TRACE("os_signal_semaphore"); if (!sem || (units < 1)) - return AE_BAD_PARAMETER; + return_ACPI_STATUS(AE_BAD_PARAMETER); if (units > 1) - return AE_SUPPORT; + return_ACPI_STATUS(AE_SUPPORT); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]\n", handle, units)); up(sem); - return AE_OK; + return_ACPI_STATUS(AE_OK); } EXPORT_SYMBOL(acpi_os_signal_semaphore); @@ -879,6 +930,14 @@ u8 acpi_os_writable(void *ptr, acpi_size len) } #endif +u32 acpi_os_get_thread_id(void) +{ + if (!in_atomic()) + return current->pid; + + return 0; +} + acpi_status acpi_os_signal(u32 function, void *info) { switch (function) { @@ -1003,10 +1062,10 @@ EXPORT_SYMBOL(max_cstate); * handle is a pointer to the spinlock_t. */ -acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp) +acpi_cpu_flags acpi_os_acquire_lock(acpi_handle handle) { acpi_cpu_flags flags; - spin_lock_irqsave(lockp, flags); + spin_lock_irqsave((spinlock_t *) handle, flags); return flags; } @@ -1014,9 +1073,9 @@ acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp) * Release a spinlock. See above. */ -void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags) +void acpi_os_release_lock(acpi_handle handle, acpi_cpu_flags flags) { - spin_unlock_irqrestore(lockp, flags); + spin_unlock_irqrestore((spinlock_t *) handle, flags); } #ifndef ACPI_USE_LOCAL_CACHE @@ -1025,12 +1084,12 @@ void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags) * * FUNCTION: acpi_os_create_cache * - * PARAMETERS: name - Ascii name for the cache - * size - Size of each cached object - * depth - Maximum depth of the cache (in objects) - * cache - Where the new cache object is returned + * PARAMETERS: CacheName - Ascii name for the cache + * ObjectSize - Size of each cached object + * MaxDepth - Maximum depth of the cache (in objects) + * ReturnCache - Where the new cache object is returned * - * RETURN: status + * RETURN: Status * * DESCRIPTION: Create a cache object * @@ -1040,10 +1099,7 @@ acpi_status acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache) { *cache = kmem_cache_create(name, size, 0, 0, NULL, NULL); - if (cache == NULL) - return AE_ERROR; - else - return AE_OK; + return AE_OK; } /******************************************************************************* @@ -1103,52 +1159,25 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object) return (AE_OK); } -/****************************************************************************** - * - * FUNCTION: acpi_os_validate_interface - * - * PARAMETERS: interface - Requested interface to be validated - * - * RETURN: AE_OK if interface is supported, AE_SUPPORT otherwise - * - * DESCRIPTION: Match an interface string to the interfaces supported by the - * host. Strings originate from an AML call to the _OSI method. - * - *****************************************************************************/ - -acpi_status -acpi_os_validate_interface (char *interface) -{ - - return AE_SUPPORT; -} - - -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: acpi_os_validate_address + * FUNCTION: acpi_os_acquire_object * - * PARAMETERS: space_id - ACPI space ID - * address - Physical address - * length - Address length + * PARAMETERS: Cache - Handle to cache object + * ReturnObject - Where the object is returned * - * RETURN: AE_OK if address/length is valid for the space_id. Otherwise, - * should return AE_AML_ILLEGAL_ADDRESS. + * RETURN: Status * - * DESCRIPTION: Validate a system address via the host OS. Used to validate - * the addresses accessed by AML operation regions. + * DESCRIPTION: Get an object from the specified cache. If cache is empty, + * the object is allocated. * - *****************************************************************************/ + ******************************************************************************/ -acpi_status -acpi_os_validate_address ( - u8 space_id, - acpi_physical_address address, - acpi_size length) +void *acpi_os_acquire_object(acpi_cache_t * cache) { - - return AE_OK; + void *object = kmem_cache_alloc(cache, GFP_KERNEL); + WARN_ON(!object); + return object; } - #endif