Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 367590
b: refs/heads/master
c: 58892c9
h: refs/heads/master
v: v3
  • Loading branch information
Bob Moore authored and Rafael J. Wysocki committed Apr 12, 2013
1 parent 1d8b29d commit dccf3d8
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 36 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 475df486f5191ce0671b99aff029b38bff7a72f1
refs/heads/master: 58892c962a0f8b7187b036e787223365864bde3f
1 change: 1 addition & 0 deletions trunk/drivers/acpi/acpica/acglobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
*/
ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock; /* For GPE data structs and registers */
ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock; /* For ACPI H/W except GPE registers */
ACPI_EXTERN acpi_spinlock acpi_gbl_reference_count_lock;

/* Mutex for _OSI support */

Expand Down
82 changes: 48 additions & 34 deletions trunk/drivers/acpi/acpica/utdelete.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,85 +359,100 @@ void acpi_ut_delete_internal_object_list(union acpi_operand_object **obj_list)
* FUNCTION: acpi_ut_update_ref_count
*
* PARAMETERS: object - Object whose ref count is to be updated
* action - What to do
* action - What to do (REF_INCREMENT or REF_DECREMENT)
*
* RETURN: New ref count
* RETURN: None. Sets new reference count within the object
*
* DESCRIPTION: Modify the ref count and return it.
* DESCRIPTION: Modify the reference count for an internal acpi object
*
******************************************************************************/

static void
acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
{
u16 count;
u16 new_count;
u16 original_count;
u16 new_count = 0;
acpi_cpu_flags lock_flags;

ACPI_FUNCTION_NAME(ut_update_ref_count);

if (!object) {
return;
}

count = object->common.reference_count;
new_count = count;

/*
* Perform the reference count action (increment, decrement, force delete)
* Always get the reference count lock. Note: Interpreter and/or
* Namespace is not always locked when this function is called.
*/
lock_flags = acpi_os_acquire_lock(acpi_gbl_reference_count_lock);
original_count = object->common.reference_count;

/* Perform the reference count action (increment, decrement) */

switch (action) {
case REF_INCREMENT:

new_count++;
new_count = original_count + 1;
object->common.reference_count = new_count;
acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);

/* The current reference count should never be zero here */

if (!original_count) {
ACPI_WARNING((AE_INFO,
"Obj %p, Reference Count was zero before increment\n",
object));
}

ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Obj %p Refs=%X, [Incremented]\n",
object, new_count));
"Obj %p Type %.2X Refs %.2X [Incremented]\n",
object, object->common.type, new_count));
break;

case REF_DECREMENT:

if (count < 1) {
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Obj %p Refs=%X, can't decrement! (Set to 0)\n",
object, new_count));

new_count = 0;
} else {
new_count--;
/* The current reference count must be non-zero */

ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Obj %p Refs=%X, [Decremented]\n",
object, new_count));
if (original_count) {
new_count = original_count - 1;
object->common.reference_count = new_count;
}

if (object->common.type == ACPI_TYPE_METHOD) {
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Method Obj %p Refs=%X, [Decremented]\n",
object, new_count));
acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);

if (!original_count) {
ACPI_WARNING((AE_INFO,
"Obj %p, Reference Count is already zero, cannot decrement\n",
object));
}

object->common.reference_count = new_count;
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Obj %p Type %.2X Refs %.2X [Decremented]\n",
object, object->common.type, new_count));

/* Actually delete the object on a reference count of zero */

if (new_count == 0) {
acpi_ut_delete_internal_obj(object);
}
break;

default:

ACPI_ERROR((AE_INFO, "Unknown action (0x%X)", action));
break;
acpi_os_release_lock(acpi_gbl_reference_count_lock, lock_flags);
ACPI_ERROR((AE_INFO, "Unknown Reference Count action (0x%X)",
action));
return;
}

/*
* Sanity check the reference count, for debug purposes only.
* (A deleted object will have a huge reference count)
*/
if (count > ACPI_MAX_REFERENCE_COUNT) {
if (new_count > ACPI_MAX_REFERENCE_COUNT) {
ACPI_WARNING((AE_INFO,
"Large Reference Count (0x%X) in object %p",
count, object));
"Large Reference Count (0x%X) in object %p, Type=0x%.2X",
new_count, object, object->common.type));
}
}

Expand Down Expand Up @@ -702,7 +717,6 @@ void acpi_ut_remove_reference(union acpi_operand_object *object)
/*
* Allow a NULL pointer to be passed in, just ignore it. This saves
* each caller from having to check. Also, ignore NS nodes.
*
*/
if (!object ||
(ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_NAMED)) {
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/acpi/acpica/utmutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ acpi_status acpi_ut_mutex_initialize(void)
}
}

/* Create the spinlocks for use at interrupt level */
/* Create the spinlocks for use at interrupt level or for speed */

status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
if (ACPI_FAILURE (status)) {
Expand All @@ -93,7 +93,13 @@ acpi_status acpi_ut_mutex_initialize(void)
return_ACPI_STATUS (status);
}

status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}

/* Mutex for _OSI support */

status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
Expand Down Expand Up @@ -136,6 +142,7 @@ void acpi_ut_mutex_terminate(void)

acpi_os_delete_lock(acpi_gbl_gpe_lock);
acpi_os_delete_lock(acpi_gbl_hardware_lock);
acpi_os_delete_lock(acpi_gbl_reference_count_lock);

/* Delete the reader/writer lock */

Expand Down

0 comments on commit dccf3d8

Please sign in to comment.