mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-09 01:28:05 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
511
drivers/acpi/acpica/evgpeblk.c
Normal file
511
drivers/acpi/acpica/evgpeblk.c
Normal file
|
@ -0,0 +1,511 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Module Name: evgpeblk - GPE block creation and initialization.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2014, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "acevents.h"
|
||||
#include "acnamesp.h"
|
||||
|
||||
#define _COMPONENT ACPI_EVENTS
|
||||
ACPI_MODULE_NAME("evgpeblk")
|
||||
#if (!ACPI_REDUCED_HARDWARE) /* Entire module */
|
||||
/* Local prototypes */
|
||||
static acpi_status
|
||||
acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
|
||||
u32 interrupt_number);
|
||||
|
||||
static acpi_status
|
||||
acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_install_gpe_block
|
||||
*
|
||||
* PARAMETERS: gpe_block - New GPE block
|
||||
* interrupt_number - Xrupt to be associated with this
|
||||
* GPE block
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Install new GPE block with mutex support
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ev_install_gpe_block(struct acpi_gpe_block_info *gpe_block,
|
||||
u32 interrupt_number)
|
||||
{
|
||||
struct acpi_gpe_block_info *next_gpe_block;
|
||||
struct acpi_gpe_xrupt_info *gpe_xrupt_block;
|
||||
acpi_status status;
|
||||
acpi_cpu_flags flags;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_install_gpe_block);
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
status =
|
||||
acpi_ev_get_gpe_xrupt_block(interrupt_number, &gpe_xrupt_block);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
||||
/* Install the new block at the end of the list with lock */
|
||||
|
||||
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
|
||||
if (gpe_xrupt_block->gpe_block_list_head) {
|
||||
next_gpe_block = gpe_xrupt_block->gpe_block_list_head;
|
||||
while (next_gpe_block->next) {
|
||||
next_gpe_block = next_gpe_block->next;
|
||||
}
|
||||
|
||||
next_gpe_block->next = gpe_block;
|
||||
gpe_block->previous = next_gpe_block;
|
||||
} else {
|
||||
gpe_xrupt_block->gpe_block_list_head = gpe_block;
|
||||
}
|
||||
|
||||
gpe_block->xrupt_block = gpe_xrupt_block;
|
||||
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
|
||||
|
||||
unlock_and_exit:
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_delete_gpe_block
|
||||
*
|
||||
* PARAMETERS: gpe_block - Existing GPE block
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Remove a GPE block
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_cpu_flags flags;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_install_gpe_block);
|
||||
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Disable all GPEs in this block */
|
||||
|
||||
status =
|
||||
acpi_hw_disable_gpe_block(gpe_block->xrupt_block, gpe_block, NULL);
|
||||
|
||||
if (!gpe_block->previous && !gpe_block->next) {
|
||||
|
||||
/* This is the last gpe_block on this interrupt */
|
||||
|
||||
status = acpi_ev_delete_gpe_xrupt(gpe_block->xrupt_block);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
} else {
|
||||
/* Remove the block on this interrupt with lock */
|
||||
|
||||
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
|
||||
if (gpe_block->previous) {
|
||||
gpe_block->previous->next = gpe_block->next;
|
||||
} else {
|
||||
gpe_block->xrupt_block->gpe_block_list_head =
|
||||
gpe_block->next;
|
||||
}
|
||||
|
||||
if (gpe_block->next) {
|
||||
gpe_block->next->previous = gpe_block->previous;
|
||||
}
|
||||
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
|
||||
}
|
||||
|
||||
acpi_current_gpe_count -= gpe_block->gpe_count;
|
||||
|
||||
/* Free the gpe_block */
|
||||
|
||||
ACPI_FREE(gpe_block->register_info);
|
||||
ACPI_FREE(gpe_block->event_info);
|
||||
ACPI_FREE(gpe_block);
|
||||
|
||||
unlock_and_exit:
|
||||
status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_create_gpe_info_blocks
|
||||
*
|
||||
* PARAMETERS: gpe_block - New GPE block
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Create the register_info and event_info blocks for this GPE block
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static acpi_status
|
||||
acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
|
||||
{
|
||||
struct acpi_gpe_register_info *gpe_register_info = NULL;
|
||||
struct acpi_gpe_event_info *gpe_event_info = NULL;
|
||||
struct acpi_gpe_event_info *this_event;
|
||||
struct acpi_gpe_register_info *this_register;
|
||||
u32 i;
|
||||
u32 j;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_create_gpe_info_blocks);
|
||||
|
||||
/* Allocate the GPE register information block */
|
||||
|
||||
gpe_register_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->
|
||||
register_count *
|
||||
sizeof(struct
|
||||
acpi_gpe_register_info));
|
||||
if (!gpe_register_info) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Could not allocate the GpeRegisterInfo table"));
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the GPE event_info block. There are eight distinct GPEs
|
||||
* per register. Initialization to zeros is sufficient.
|
||||
*/
|
||||
gpe_event_info = ACPI_ALLOCATE_ZEROED((acpi_size) gpe_block->gpe_count *
|
||||
sizeof(struct
|
||||
acpi_gpe_event_info));
|
||||
if (!gpe_event_info) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Could not allocate the GpeEventInfo table"));
|
||||
status = AE_NO_MEMORY;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
/* Save the new Info arrays in the GPE block */
|
||||
|
||||
gpe_block->register_info = gpe_register_info;
|
||||
gpe_block->event_info = gpe_event_info;
|
||||
|
||||
/*
|
||||
* Initialize the GPE Register and Event structures. A goal of these
|
||||
* tables is to hide the fact that there are two separate GPE register
|
||||
* sets in a given GPE hardware block, the status registers occupy the
|
||||
* first half, and the enable registers occupy the second half.
|
||||
*/
|
||||
this_register = gpe_register_info;
|
||||
this_event = gpe_event_info;
|
||||
|
||||
for (i = 0; i < gpe_block->register_count; i++) {
|
||||
|
||||
/* Init the register_info for this GPE register (8 GPEs) */
|
||||
|
||||
this_register->base_gpe_number = (u16)
|
||||
(gpe_block->block_base_number +
|
||||
(i * ACPI_GPE_REGISTER_WIDTH));
|
||||
|
||||
this_register->status_address.address = gpe_block->address + i;
|
||||
|
||||
this_register->enable_address.address =
|
||||
gpe_block->address + i + gpe_block->register_count;
|
||||
|
||||
this_register->status_address.space_id = gpe_block->space_id;
|
||||
this_register->enable_address.space_id = gpe_block->space_id;
|
||||
this_register->status_address.bit_width =
|
||||
ACPI_GPE_REGISTER_WIDTH;
|
||||
this_register->enable_address.bit_width =
|
||||
ACPI_GPE_REGISTER_WIDTH;
|
||||
this_register->status_address.bit_offset = 0;
|
||||
this_register->enable_address.bit_offset = 0;
|
||||
|
||||
/* Init the event_info for each GPE within this register */
|
||||
|
||||
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
|
||||
this_event->gpe_number =
|
||||
(u8) (this_register->base_gpe_number + j);
|
||||
this_event->register_info = this_register;
|
||||
this_event++;
|
||||
}
|
||||
|
||||
/* Disable all GPEs within this register */
|
||||
|
||||
status = acpi_hw_write(0x00, &this_register->enable_address);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
/* Clear any pending GPE events within this register */
|
||||
|
||||
status = acpi_hw_write(0xFF, &this_register->status_address);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
this_register++;
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
|
||||
error_exit:
|
||||
if (gpe_register_info) {
|
||||
ACPI_FREE(gpe_register_info);
|
||||
}
|
||||
if (gpe_event_info) {
|
||||
ACPI_FREE(gpe_event_info);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_create_gpe_block
|
||||
*
|
||||
* PARAMETERS: gpe_device - Handle to the parent GPE block
|
||||
* gpe_block_address - Address and space_ID
|
||||
* register_count - Number of GPE register pairs in the block
|
||||
* gpe_block_base_number - Starting GPE number for the block
|
||||
* interrupt_number - H/W interrupt for the block
|
||||
* return_gpe_block - Where the new block descriptor is returned
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Create and Install a block of GPE registers. All GPEs within
|
||||
* the block are disabled at exit.
|
||||
* Note: Assumes namespace is locked.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
u64 address,
|
||||
u8 space_id,
|
||||
u32 register_count,
|
||||
u16 gpe_block_base_number,
|
||||
u32 interrupt_number,
|
||||
struct acpi_gpe_block_info **return_gpe_block)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_gpe_block_info *gpe_block;
|
||||
struct acpi_gpe_walk_info walk_info;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_create_gpe_block);
|
||||
|
||||
if (!register_count) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/* Allocate a new GPE block */
|
||||
|
||||
gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info));
|
||||
if (!gpe_block) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Initialize the new GPE block */
|
||||
|
||||
gpe_block->address = address;
|
||||
gpe_block->space_id = space_id;
|
||||
gpe_block->node = gpe_device;
|
||||
gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH);
|
||||
gpe_block->initialized = FALSE;
|
||||
gpe_block->register_count = register_count;
|
||||
gpe_block->block_base_number = gpe_block_base_number;
|
||||
|
||||
/*
|
||||
* Create the register_info and event_info sub-structures
|
||||
* Note: disables and clears all GPEs in the block
|
||||
*/
|
||||
status = acpi_ev_create_gpe_info_blocks(gpe_block);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_FREE(gpe_block);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/* Install the new block in the global lists */
|
||||
|
||||
status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_FREE(gpe_block->register_info);
|
||||
ACPI_FREE(gpe_block->event_info);
|
||||
ACPI_FREE(gpe_block);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
acpi_gbl_all_gpes_initialized = FALSE;
|
||||
|
||||
/* Find all GPE methods (_Lxx or_Exx) for this block */
|
||||
|
||||
walk_info.gpe_block = gpe_block;
|
||||
walk_info.gpe_device = gpe_device;
|
||||
walk_info.execute_by_owner_id = FALSE;
|
||||
|
||||
status = acpi_ns_walk_namespace(ACPI_TYPE_METHOD, gpe_device,
|
||||
ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
|
||||
acpi_ev_match_gpe_method, NULL,
|
||||
&walk_info, NULL);
|
||||
|
||||
/* Return the new block */
|
||||
|
||||
if (return_gpe_block) {
|
||||
(*return_gpe_block) = gpe_block;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
|
||||
" Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
|
||||
(u32)gpe_block->block_base_number,
|
||||
(u32)(gpe_block->block_base_number +
|
||||
(gpe_block->gpe_count - 1)),
|
||||
gpe_device->name.ascii, gpe_block->register_count,
|
||||
interrupt_number,
|
||||
interrupt_number ==
|
||||
acpi_gbl_FADT.sci_interrupt ? " (SCI)" : ""));
|
||||
|
||||
/* Update global count of currently available GPEs */
|
||||
|
||||
acpi_current_gpe_count += gpe_block->gpe_count;
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ev_initialize_gpe_block
|
||||
*
|
||||
* PARAMETERS: acpi_gpe_callback
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have
|
||||
* associated methods.
|
||||
* Note: Assumes namespace is locked.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status
|
||||
acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
|
||||
struct acpi_gpe_block_info *gpe_block,
|
||||
void *ignored)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_gpe_event_info *gpe_event_info;
|
||||
u32 gpe_enabled_count;
|
||||
u32 gpe_index;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_initialize_gpe_block);
|
||||
|
||||
/*
|
||||
* Ignore a null GPE block (e.g., if no GPE block 1 exists), and
|
||||
* any GPE blocks that have been initialized already.
|
||||
*/
|
||||
if (!gpe_block || gpe_block->initialized) {
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable all GPEs that have a corresponding method and have the
|
||||
* ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block
|
||||
* must be enabled via the acpi_enable_gpe() interface.
|
||||
*/
|
||||
gpe_enabled_count = 0;
|
||||
|
||||
for (i = 0; i < gpe_block->register_count; i++) {
|
||||
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
|
||||
|
||||
/* Get the info block for this particular GPE */
|
||||
|
||||
gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j;
|
||||
gpe_event_info = &gpe_block->event_info[gpe_index];
|
||||
|
||||
/*
|
||||
* Ignore GPEs that have no corresponding _Lxx/_Exx method
|
||||
* and GPEs that are used to wake the system
|
||||
*/
|
||||
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
|
||||
ACPI_GPE_DISPATCH_NONE)
|
||||
|| ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
|
||||
== ACPI_GPE_DISPATCH_HANDLER)
|
||||
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
status = acpi_ev_add_gpe_reference(gpe_event_info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"Could not enable GPE 0x%02X",
|
||||
gpe_index +
|
||||
gpe_block->block_base_number));
|
||||
continue;
|
||||
}
|
||||
|
||||
gpe_enabled_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (gpe_enabled_count) {
|
||||
ACPI_INFO((AE_INFO,
|
||||
"Enabled %u GPEs in block %02X to %02X",
|
||||
gpe_enabled_count, (u32)gpe_block->block_base_number,
|
||||
(u32)(gpe_block->block_base_number +
|
||||
(gpe_block->gpe_count - 1))));
|
||||
}
|
||||
|
||||
gpe_block->initialized = TRUE;
|
||||
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
}
|
||||
|
||||
#endif /* !ACPI_REDUCED_HARDWARE */
|
Loading…
Add table
Add a link
Reference in a new issue