Skip to contentSkip to conversation

ACPI patches on test branch

PATCH New Len Brown 1 participant 17 messages Jun 4, 2010 – Jun 8, 2010

Subsystems (5)
x86 ACPI Suspend to RAM Hibernation +1 more subsystems
lore
Share & tools
lore

Len Brown

author reviewer
#0 lore raw

Here are the patches currently on the ACPI test branch -- beyond what is on the release branch.

git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git test

We may choose to cherry-pick some of these for 2.6.35-rc2, rather than waiting for 2.6.36, so please speak up if you have troubles with any of them.

thanks,
Len Brown, Intel Open Source Technology Center

author reviewer
#1 lore raw

PATCH 1/16 ACPI: acpi_pad: Don't needlessly mark LAPIC unstable

From: Chen Gong <[email protected]>

As suggested in Venki's suggestion in the commit 0dc698b, add LAPIC unstable detection in the acpi_pad drvier too.

---
 drivers/acpi/acpi_pad.c |   36 ++++++++++++++++++++++++------------
 1 files changed, 24 insertions(+), 12 deletions(-)
drivers/acpi/acpi_pad.c +24 -12
index d269a8f..446aced 100644
@@ -46,6 +46,8 @@ static unsigned long power_saving_mwait_eax;
 
 static unsigned char tsc_detected_unstable;
 static unsigned char tsc_marked_unstable;
+static unsigned char lapic_detected_unstable;
+static unsigned char lapic_marked_unstable;
 
 static void power_saving_mwait_init(void)
 {
@@ -75,9 +77,6 @@ static void power_saving_mwait_init(void)
 	power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
 		(highest_subcstate - 1);
 
-	for_each_online_cpu(i)
-		clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
-
 #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
 	switch (boot_cpu_data.x86_vendor) {
 	case X86_VENDOR_AMD:
@@ -86,13 +85,15 @@ static void power_saving_mwait_init(void)
 		 * AMD Fam10h TSC will tick in all
 		 * C/P/S0/S1 states when this bit is set.
 		 */
-		if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
-			return;
-
-		/*FALL THROUGH*/
+		if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
+			tsc_detected_unstable = 1;
+		if (!boot_cpu_has(X86_FEATURE_ARAT))
+			lapic_detected_unstable = 1;
+		break;
 	default:
-		/* TSC could halt in idle */
+		/* TSC & LAPIC could halt in idle */
 		tsc_detected_unstable = 1;
+		lapic_detected_unstable = 1;
 	}
 #endif
 }
@@ -180,10 +181,20 @@ static int power_saving_thread(void *data)
 				mark_tsc_unstable("TSC halts in idle");
 				tsc_marked_unstable = 1;
 			}
+			if (lapic_detected_unstable && !lapic_marked_unstable) {
+				int i;
+				/* LAPIC could halt in idle, so notify users */
+				for_each_online_cpu(i)
+					clockevents_notify(
+						CLOCK_EVT_NOTIFY_BROADCAST_ON,
+						&i);
+				lapic_marked_unstable = 1;
+			}
 			local_irq_disable();
 			cpu = smp_processor_id();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
-				&cpu);
+			if (lapic_marked_unstable)
+				clockevents_notify(
+					CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu);
 			stop_critical_timings();
 
 			__monitor((void *)&current_thread_info()->flags, 0, 0);
@@ -192,8 +203,9 @@ static int power_saving_thread(void *data)
 				__mwait(power_saving_mwait_eax, 1);
 
 			start_critical_timings();
-			clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
-				&cpu);
+			if (lapic_marked_unstable)
+				clockevents_notify(
+					CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu);
 			local_irq_enable();
 
 			if (jiffies > expire_time) {
Signature · 1 line
1.6.0.6
author reviewer
#2 lore raw

PATCH 2/16 ACPICA: Add comment: _BCL cannot be sorted on the fly

In reply to Len Brown

From: Bob Moore <[email protected]>

Because of package index values used for _BQC and _BCM.

---
 drivers/acpi/acpica/nsrepair2.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/acpi/acpica/nsrepair2.c +7 -0
index 61bd0f6..4009498 100644
@@ -112,6 +112,13 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _PSS: Sort the list descending by Power
  * _TSS: Sort the list descending by Power
+ *
+ * Names that must be packages, but cannot be sorted:
+ *
+ * _BCL: Values are tied to the Package index where they appear, and cannot
+ * be moved or sorted. These index values are used for _BQC and _BCM.
+ * However, we can fix the case where a buffer is returned, by converting
+ * it to a Package of integers.
  */
 static const struct acpi_repair_info acpi_ns_repairable_names[] = {
 	{"_ALR", acpi_ns_repair_ALR},
Signature · 1 line
1.6.0.6
author reviewer
#3 lore raw

PATCH 3/16 ACPICA: Fix namestring associated with AE_NO_HANDLER exception

In reply to Len Brown

From: Bob Moore <[email protected]>

Was incorrectly AE_WAKE_ONLY_GPE.

---
 include/acpi/acexcep.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/acexcep.h +1 -1
index 5958d78..17714be 100644
@@ -212,7 +212,7 @@ char const *acpi_gbl_exception_names_env[] = {
 	"AE_NO_GLOBAL_LOCK",
 	"AE_ABORT_METHOD",
 	"AE_SAME_HANDLER",
-	"AE_WAKE_ONLY_GPE",
+	"AE_NO_HANDLER",
 	"AE_OWNER_ID_LIMIT"
 };
 
Signature · 1 line
1.6.0.6
author reviewer
#4 lore raw

PATCH 4/16 ACPICA: iASL/Core: Add support for _WDG/_WED MS methods

In reply to Len Brown

From: Bob Moore <[email protected]>

These objects are defined by "Windows Instrumentation", and are not part of the ACPI spec. Adds compiler support and runtime typechecking support in the ACPICA core. ACPICA BZ 860.

http://www.acpica.org/bugzilla/show_bug.cgi?id=860

---
 drivers/acpi/acpica/acpredef.h |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)
drivers/acpi/acpica/acpredef.h +7 -6
index 9711608..10998d3 100644
@@ -503,15 +503,16 @@ static const union acpi_predefined_info predefined_names[] =
 	{{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}},
 			  {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */
 
-	{{{0,0,0,0}, 0,0}} /* Table terminator */
-};
+	/* _WDG/_WED are MS extensions defined by "Windows Instrumentation" */
 
-#if 0
-	/* Not implemented */
+	{{"_WDG", 0, ACPI_RTYPE_BUFFER}},
+	{{"_WED", 1,
+	  ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}},
 
-	{{"_WDG", 0, ACPI_RTYPE_BUFFER}},  /* MS Extension */
-	{{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */
+	{{{0, 0, 0, 0}, 0, 0}}  /* Table terminator */
+};
 
+#if 0
 	/* This is an internally implemented control method, no need to check */
 	{{"_OSI", 1, ACPI_RTYPE_INTEGER}},
 
Signature · 1 line
1.6.0.6
author reviewer
#5 lore raw

PATCH 5/16 ACPICA: Expand initialization counters to 32 bits

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

Expand the various initialization counters from 16-bit to 32-bit. Allows for very large namespaces.

---
 drivers/acpi/acpica/acstruct.h |   26 +++++++++++++-------------
 drivers/acpi/acpica/dsinit.c   |   14 +++++++-------
 drivers/acpi/acpica/nsinit.c   |    8 ++++----
 3 files changed, 24 insertions(+), 24 deletions(-)
drivers/acpi/acpica/acstruct.h +13 -13
index 161bc0e..0e2c66a 100644
@@ -127,22 +127,22 @@ struct acpi_walk_state {
 	acpi_parse_upwards ascending_callback;
 };
 
-/* Info used by acpi_ps_init_objects */
+/* Info used by acpi_ns_initialize_objects and acpi_ds_initialize_objects */
 
 struct acpi_init_walk_info {
-	u16 method_count;
-	u16 device_count;
-	u16 op_region_count;
-	u16 field_count;
-	u16 buffer_count;
-	u16 package_count;
-	u16 op_region_init;
-	u16 field_init;
-	u16 buffer_init;
-	u16 package_init;
-	u16 object_count;
-	acpi_owner_id owner_id;
 	u32 table_index;
+	u32 object_count;
+	u32 method_count;
+	u32 device_count;
+	u32 op_region_count;
+	u32 field_count;
+	u32 buffer_count;
+	u32 package_count;
+	u32 op_region_init;
+	u32 field_init;
+	u32 buffer_init;
+	u32 package_init;
+	acpi_owner_id owner_id;
 };
 
 struct acpi_get_devices_info {
drivers/acpi/acpica/dsinit.c +7 -7
index abe1403..cc4a38c 100644
@@ -171,12 +171,12 @@ acpi_ds_initialize_objects(u32 table_index,
 			  "**** Starting initialization of namespace objects ****\n"));
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "Parsing all Control Methods:"));
 
-	info.method_count = 0;
-	info.op_region_count = 0;
-	info.object_count = 0;
-	info.device_count = 0;
-	info.table_index = table_index;
+	/* Set all init info to zero */
+
+	ACPI_MEMSET(&info, 0, sizeof(struct acpi_init_walk_info));
+
 	info.owner_id = owner_id;
+	info.table_index = table_index;
 
 	/* Walk entire namespace from the supplied root */
 
@@ -204,13 +204,13 @@ acpi_ds_initialize_objects(u32 table_index,
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+			      "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
 			      table->signature, owner_id, info.object_count,
 			      info.device_count, info.method_count,
 			      info.op_region_count));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "%hd Methods, %hd Regions\n", info.method_count,
+			  "%u Methods, %u Regions\n", info.method_count,
 			  info.op_region_count));
 
 	return_ACPI_STATUS(AE_OK);
drivers/acpi/acpica/nsinit.c +4 -4
index 9bd6f05..b3d88d8 100644
@@ -103,8 +103,8 @@ acpi_status acpi_ns_initialize_objects(void)
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
-			      "Buffers %hd/%hd Packages (%hd nodes)\n",
+			      "\nInitialized %u/%u Regions %u/%u Fields %u/%u "
+			      "Buffers %u/%u Packages (%u nodes)\n",
 			      info.op_region_init, info.op_region_count,
 			      info.field_init, info.field_count,
 			      info.buffer_init, info.buffer_count,
@@ -112,9 +112,9 @@ acpi_status acpi_ns_initialize_objects(void)
 			      info.object_count));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "%hd Control Methods found\n", info.method_count));
+			  "%u Control Methods found\n", info.method_count));
 	ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-			  "%hd Op Regions found\n", info.op_region_count));
+			  "%u Op Regions found\n", info.op_region_count));
 
 	return_ACPI_STATUS(AE_OK);
 }
Signature · 1 line
1.6.0.6
author reviewer
#6 lore raw

PATCH 6/16 ACPICA: Limit maximum time for Sleep() operator

In reply to Len Brown

From: Bob Moore <[email protected]>

To prevent accidental deep sleeps, limit the maximum time that Sleep() will sleep. Configurable, default maximum is two seconds. ACPICA bugzilla 854.

http://www.acpica.org/bugzilla/show_bug.cgi?id=854

---
 drivers/acpi/acpica/acconfig.h |    4 ++++
 drivers/acpi/acpica/exsystem.c |    8 ++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)
drivers/acpi/acpica/acconfig.h +4 -0
index 33181ad..b17d8de 100644
@@ -119,6 +119,10 @@
 
 #define ACPI_MAX_LOOP_ITERATIONS        0xFFFF
 
+/* Maximum sleep allowed via Sleep() operator */
+
+#define ACPI_MAX_SLEEP                  20000	/* Two seconds */
+
 /******************************************************************************
  *
  * ACPI Specification constants (Do not change unless the specification changes)
drivers/acpi/acpica/exsystem.c +8 -0
index 6d32e09..675aaa9 100644
@@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long)
 
 	acpi_ex_relinquish_interpreter();
 
+	/*
+	 * For compatibility with other ACPI implementations and to prevent
+	 * accidental deep sleeps, limit the sleep time to something reasonable.
+	 */
+	if (how_long > ACPI_MAX_SLEEP) {
+		how_long = ACPI_MAX_SLEEP;
+	}
+
 	acpi_os_sleep(how_long);
 
 	/* And now we must get the interpreter again */
Signature · 1 line
1.6.0.6
author reviewer
#7 lore raw

PATCH 7/16 ACPICA: Core: Replace all %d format specifiers with %u (unsigned)

In reply to Len Brown

From: Bob Moore <[email protected]>

With only a few exceptions, ACPICA does not use signed integers. Therefore, %d is incorrect.

---
 drivers/acpi/acpica/dsmethod.c |    2 +-
 drivers/acpi/acpica/dsmthdat.c |   10 +++++-----
 drivers/acpi/acpica/dsutils.c  |    4 ++--
 drivers/acpi/acpica/exdump.c   |    4 ++--
 drivers/acpi/acpica/exfldio.c  |    4 ++--
 drivers/acpi/acpica/exprep.c   |   14 +++++++-------
 drivers/acpi/acpica/exregion.c |    6 +++---
 drivers/acpi/acpica/hwsleep.c  |    2 +-
 drivers/acpi/acpica/nsaccess.c |    4 ++--
 drivers/acpi/acpica/nsdump.c   |    2 +-
 drivers/acpi/acpica/nsparse.c  |    4 ++--
 11 files changed, 28 insertions(+), 28 deletions(-)
drivers/acpi/acpica/dsmethod.c +1 -1
index 2a9a561..0084633 100644
@@ -605,7 +605,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 		 * we immediately reuse it for the next thread executing this method
 		 */
 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-				  "*** Completed execution of one thread, %d threads remaining\n",
+				  "*** Completed execution of one thread, %u threads remaining\n",
 				  method_desc->method.thread_count));
 	} else {
 		/* This is the only executing thread for this method */
drivers/acpi/acpica/dsmthdat.c +5 -5
index f3d52f5..d5e927f 100644
@@ -146,7 +146,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
 
 	for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
 		if (walk_state->local_variables[index].object) {
-			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
+			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
 					  index,
 					  walk_state->local_variables[index].
 					  object));
@@ -162,7 +162,7 @@ void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
 
 	for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
 		if (walk_state->arguments[index].object) {
-			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
+			ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
 					  index,
 					  walk_state->arguments[index].object));
 
@@ -226,7 +226,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params,
 		index++;
 	}
 
-	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%d args passed to method\n", index));
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%u args passed to method\n", index));
 	return_ACPI_STATUS(AE_OK);
 }
 
@@ -323,7 +323,7 @@ acpi_ds_method_data_set_value(u8 type,
 	ACPI_FUNCTION_TRACE(ds_method_data_set_value);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-			  "NewObj %p Type %2.2X, Refs=%d [%s]\n", object,
+			  "NewObj %p Type %2.2X, Refs=%u [%s]\n", object,
 			  type, object->common.reference_count,
 			  acpi_ut_get_type_name(object->common.type)));
 
@@ -543,7 +543,7 @@ acpi_ds_store_object_to_local(u8 type,
 	union acpi_operand_object *new_obj_desc;
 
 	ACPI_FUNCTION_TRACE(ds_store_object_to_local);
-	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n",
+	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
 			  type, index, obj_desc));
 
 	/* Parameter validation */
drivers/acpi/acpica/dsutils.c +2 -2
index 306c62a..15135c2 100644
@@ -746,7 +746,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 		index--;
 
 		ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-				  "Arg #%d (%p) done, Arg1=%p\n", index, arg,
+				  "Arg #%u (%p) done, Arg1=%p\n", index, arg,
 				  first_arg));
 	}
 
@@ -760,7 +760,7 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state,
 	 */
 	acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state);
 
-	ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index));
+	ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %u", index));
 	return_ACPI_STATUS(status);
 }
 
drivers/acpi/acpica/exdump.c +2 -2
index d39d438..cdb66d1 100644
@@ -742,7 +742,7 @@ acpi_ex_dump_operands(union acpi_operand_object **operands,
 	}
 
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-			  "**** Start operand dump for opcode [%s], %d operands\n",
+			  "**** Start operand dump for opcode [%s], %u operands\n",
 			  opcode_name, num_operands));
 
 	if (num_operands == 0) {
@@ -945,7 +945,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
 
 	case ACPI_TYPE_PACKAGE:
 
-		acpi_os_printf("[Package] Contains %d Elements:\n",
+		acpi_os_printf("[Package] Contains %u Elements:\n",
 			       obj_desc->package.count);
 
 		for (i = 0; i < obj_desc->package.count; i++) {
drivers/acpi/acpica/exfldio.c +2 -2
index a6dc26f..0472173 100644
@@ -534,13 +534,13 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
 	if (ACPI_SUCCESS(status)) {
 		if (read_write == ACPI_READ) {
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "Value Read %8.8X%8.8X, Width %d\n",
+					  "Value Read %8.8X%8.8X, Width %u\n",
 					  ACPI_FORMAT_UINT64(*value),
 					  obj_desc->common_field.
 					  access_byte_width));
 		} else {
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "Value Written %8.8X%8.8X, Width %d\n",
+					  "Value Written %8.8X%8.8X, Width %u\n",
 					  ACPI_FORMAT_UINT64(*value),
 					  obj_desc->common_field.
 					  access_byte_width));
drivers/acpi/acpica/exprep.c +7 -7
index 25059da..0686f27 100644
@@ -108,11 +108,11 @@ acpi_ex_generate_access(u32 field_bit_offset,
 	field_byte_length = field_byte_end_offset - field_byte_offset;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-			  "Bit length %d, Bit offset %d\n",
+			  "Bit length %u, Bit offset %u\n",
 			  field_bit_length, field_bit_offset));
 
 	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-			  "Byte Length %d, Byte Offset %d, End Offset %d\n",
+			  "Byte Length %u, Byte Offset %u, End Offset %u\n",
 			  field_byte_length, field_byte_offset,
 			  field_byte_end_offset));
 
@@ -147,11 +147,11 @@ acpi_ex_generate_access(u32 field_bit_offset,
 			accesses = field_end_offset - field_start_offset;
 
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "AccessWidth %d end is within region\n",
+					  "AccessWidth %u end is within region\n",
 					  access_byte_width));
 
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "Field Start %d, Field End %d -- requires %d accesses\n",
+					  "Field Start %u, Field End %u -- requires %u accesses\n",
 					  field_start_offset, field_end_offset,
 					  accesses));
 
@@ -159,7 +159,7 @@ acpi_ex_generate_access(u32 field_bit_offset,
 
 			if (accesses <= 1) {
 				ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-						  "Entire field can be accessed with one operation of size %d\n",
+						  "Entire field can be accessed with one operation of size %u\n",
 						  access_byte_width));
 				return_VALUE(access_byte_width);
 			}
@@ -174,7 +174,7 @@ acpi_ex_generate_access(u32 field_bit_offset,
 			}
 		} else {
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "AccessWidth %d end is NOT within region\n",
+					  "AccessWidth %u end is NOT within region\n",
 					  access_byte_width));
 			if (access_byte_width == 1) {
 				ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
@@ -190,7 +190,7 @@ acpi_ex_generate_access(u32 field_bit_offset,
 			 * previous access
 			 */
 			ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-					  "Backing off to previous optimal access width of %d\n",
+					  "Backing off to previous optimal access width of %u\n",
 					  minimum_access_width));
 			return_VALUE(minimum_access_width);
 		}
drivers/acpi/acpica/exregion.c +3 -3
index 531000f..8819d2a 100644
@@ -194,7 +194,7 @@ acpi_ex_system_memory_space_handler(u32 function,
 	    ((u64) address - (u64) mem_info->mapped_physical_address);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "System-Memory (width %d) R/W %d Address=%8.8X%8.8X\n",
+			  "System-Memory (width %u) R/W %u Address=%8.8X%8.8X\n",
 			  bit_width, function,
 			  ACPI_FORMAT_NATIVE_UINT(address)));
 
@@ -297,7 +297,7 @@ acpi_ex_system_io_space_handler(u32 function,
 	ACPI_FUNCTION_TRACE(ex_system_io_space_handler);
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "System-IO (width %d) R/W %d Address=%8.8X%8.8X\n",
+			  "System-IO (width %u) R/W %u Address=%8.8X%8.8X\n",
 			  bit_width, function,
 			  ACPI_FORMAT_NATIVE_UINT(address)));
 
@@ -373,7 +373,7 @@ acpi_ex_pci_config_space_handler(u32 function,
 	pci_register = (u16) (u32) address;
 
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			  "Pci-Config %d (%d) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
+			  "Pci-Config %u (%u) Seg(%04x) Bus(%04x) Dev(%04x) Func(%04x) Reg(%04x)\n",
 			  function, bit_width, pci_id->segment, pci_id->bus,
 			  pci_id->device, pci_id->function, pci_register));
 
drivers/acpi/acpica/hwsleep.c +1 -1
index 36eb803..3796811 100644
@@ -307,7 +307,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
 		return_ACPI_STATUS(status);
 	}
 	ACPI_DEBUG_PRINT((ACPI_DB_INIT,
-			  "Entering sleep state [S%d]\n", sleep_state));
+			  "Entering sleep state [S%u]\n", sleep_state));
 
 	/* Clear the SLP_EN and SLP_TYP fields */
 
drivers/acpi/acpica/nsaccess.c +2 -2
index 3a28146..2cebfa9 100644
@@ -433,7 +433,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
 
 			if (search_parent_flag == ACPI_NS_NO_UPSEARCH) {
 				ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-						  "Search scope is [%4.4s], path has %d carat(s)\n",
+						  "Search scope is [%4.4s], path has %u carat(s)\n",
 						  acpi_ut_get_node_name
 						  (this_node), num_carats));
 			}
@@ -495,7 +495,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
 			path++;
 
 			ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-					  "Multi Pathname (%d Segments, Flags=%X)\n",
+					  "Multi Pathname (%u Segments, Flags=%X)\n",
 					  num_segments, flags));
 			break;
 
drivers/acpi/acpica/nsdump.c +1 -1
index 2110cc2..a54dc39 100644
@@ -441,7 +441,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
 			return (AE_OK);
 		}
 
-		acpi_os_printf("(R%d)", obj_desc->common.reference_count);
+		acpi_os_printf("(R%u)", obj_desc->common.reference_count);
 
 		switch (type) {
 		case ACPI_TYPE_METHOD:
drivers/acpi/acpica/nsparse.c +2 -2
index 27cda52..5808c89 100644
@@ -136,8 +136,8 @@ acpi_ns_one_complete_parse(u32 pass_number,
 
 	/* Parse the AML */
 
-	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %d parse\n",
-			  (unsigned)pass_number));
+	ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "*PARSE* pass %u parse\n",
+			  pass_number));
 	status = acpi_ps_parse_aml(walk_state);
 
       cleanup:
Signature · 1 line
1.6.0.6
author reviewer
#8 lore raw

PATCH 8/16 ACPICA: Expand device initialization counters to 32 bits

In reply to Len Brown

From: Bob Moore <[email protected]>

Expand the various device initialization counters from 16-bit to 32-bit. Allows for very large namespaces.

---
 drivers/acpi/acpica/acstruct.h |    6 +++---
 drivers/acpi/acpica/nsinit.c   |    4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/acpi/acpica/acstruct.h +3 -3
index 0e2c66a..6e5dd97 100644
@@ -201,11 +201,11 @@ struct acpi_evaluate_info {
 /* Info used by acpi_ns_initialize_devices */
 
 struct acpi_device_walk_info {
-	u16 device_count;
-	u16 num_STA;
-	u16 num_INI;
 	struct acpi_table_desc *table_desc;
 	struct acpi_evaluate_info *evaluate_info;
+	u32 device_count;
+	u32 num_STA;
+	u32 num_INI;
 };
 
 /* TBD: [Restructure] Merge with struct above */
drivers/acpi/acpica/nsinit.c +2 -2
index b3d88d8..8009e71 100644
@@ -199,8 +199,8 @@ acpi_status acpi_ns_initialize_devices(void)
 	}
 
 	ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
-			      "\nExecuted %hd _INI methods requiring %hd _STA executions "
-			      "(examined %hd objects)\n",
+			      "\nExecuted %u _INI methods requiring %u _STA executions "
+			      "(examined %u objects)\n",
 			      info.num_INI, info.num_STA, info.device_count));
 
 	return_ACPI_STATUS(status);
Signature · 1 line
1.6.0.6
author reviewer
#9 lore raw

PATCH 9/16 ACPICA: Truncate I/O addresses to 16 bits for Windows compatibility

In reply to Len Brown

From: Matthew Garrett <[email protected]>

This feature is optional and is enabled if the BIOS requests any Windows OSI strings. It can also be enabled by the host OS.

---
 drivers/acpi/acpica/acglobal.h |    8 ++++++++
 drivers/acpi/acpica/hwvalid.c  |   12 ++++++++++++
 drivers/acpi/acpica/nsinit.c   |    9 +++++++++
 include/acpi/acpixf.h          |    1 +
 4 files changed, 30 insertions(+), 0 deletions(-)
drivers/acpi/acpica/acglobal.h +8 -0
index 9070f1f..899d68a 100644
@@ -125,6 +125,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE);
  */
 u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE);
 
+/*
+ * Optionally truncate I/O addresses to 16 bits. Provides compatibility
+ * with other ACPI implementations. NOTE: During ACPICA initialization,
+ * this value is set to TRUE if any Windows OSI strings have been
+ * requested by the BIOS.
+ */
+u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE);
+
 /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
 
 struct acpi_table_fadt acpi_gbl_FADT;
drivers/acpi/acpica/hwvalid.c +12 -0
index c10d587..e1d9c77 100644
@@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
 	u32 one_byte;
 	u32 i;
 
+	/* Truncate address to 16 bits if requested */
+
+	if (acpi_gbl_truncate_io_addresses) {
+		address &= ACPI_UINT16_MAX;
+	}
+
 	/* Validate the entire request and perform the I/O */
 
 	status = acpi_hw_validate_io_request(address, width);
@@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
 	acpi_status status;
 	u32 i;
 
+	/* Truncate address to 16 bits if requested */
+
+	if (acpi_gbl_truncate_io_addresses) {
+		address &= ACPI_UINT16_MAX;
+	}
+
 	/* Validate the entire request and perform the I/O */
 
 	status = acpi_hw_validate_io_request(address, width);
drivers/acpi/acpica/nsinit.c +9 -0
index 8009e71..f0e49df 100644
@@ -193,6 +193,15 @@ acpi_status acpi_ns_initialize_devices(void)
 					acpi_ns_init_one_device, NULL, &info,
 					NULL);
 
+	/*
+	 * Any _OSI requests should be completed by now. If the BIOS has
+	 * requested any Windows OSI strings, we will always truncate
+	 * I/O addresses to 16 bits -- for Windows compatibility.
+	 */
+	if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) {
+		acpi_gbl_truncate_io_addresses = TRUE;
+	}
+
 	ACPI_FREE(info.evaluate_info);
 	if (ACPI_FAILURE(status)) {
 		goto error_exit;
include/acpi/acpixf.h +1 -0
index 0e4ab1f..1371cc9 100644
@@ -69,6 +69,7 @@ extern acpi_name acpi_gbl_trace_method_name;
 extern u32 acpi_gbl_trace_flags;
 extern u8 acpi_gbl_enable_aml_debug_object;
 extern u8 acpi_gbl_copy_dsdt_locally;
+extern u8 acpi_gbl_truncate_io_addresses;
 
 extern u32 acpi_current_gpe_count;
 extern struct acpi_table_fadt acpi_gbl_FADT;
Signature · 1 line
1.6.0.6
author reviewer
#10 lore raw

PATCH 10/16 ACPICA: Performance enhancement for namespace search and access

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

This change enhances the performance of namespace searches and walks by adding a backpointer to the parent in each namespace node. On large namespaces, this change can improve overall ACPI performance by up to 9X. Adding a pointer to each namespace node increases the overall size of the internal namespace by about 5%, since each namespace entry usually consists of both a namespace node and an ACPI operand object.

---
 drivers/acpi/acpica/aclocal.h  |    5 +-
 drivers/acpi/acpica/acnamesp.h |    7 ---
 drivers/acpi/acpica/dsmthdat.c |    6 +--
 drivers/acpi/acpica/dsopcode.c |    6 +-
 drivers/acpi/acpica/evrgnini.c |   10 ++--
 drivers/acpi/acpica/exdump.c   |    2 +-
 drivers/acpi/acpica/nsaccess.c |    5 +-
 drivers/acpi/acpica/nsalloc.c  |   74 +++++++++-----------------
 drivers/acpi/acpica/nsinit.c   |    4 +-
 drivers/acpi/acpica/nsnames.c  |    4 +-
 drivers/acpi/acpica/nssearch.c |   15 +-----
 drivers/acpi/acpica/nsutils.c  |  113 ----------------------------------------
 drivers/acpi/acpica/nswalk.c   |   15 +----
 drivers/acpi/acpica/nsxfobj.c  |    2 +-
 drivers/acpi/acpica/utglobal.c |    2 +-
 15 files changed, 52 insertions(+), 218 deletions(-)
drivers/acpi/acpica/aclocal.h +3 -2
index 147a7e6..eb2d420 100644
@@ -184,8 +184,9 @@ struct acpi_namespace_node {
 	u8 flags;		/* Miscellaneous flags */
 	acpi_owner_id owner_id;	/* Node creator */
 	union acpi_name_union name;	/* ACPI Name, always 4 chars per ACPI spec */
+	struct acpi_namespace_node *parent;	/* Parent node */
 	struct acpi_namespace_node *child;	/* First child */
-	struct acpi_namespace_node *peer;	/* Peer. Parent if ANOBJ_END_OF_PEER_LIST set */
+	struct acpi_namespace_node *peer;	/* First peer */
 
 	/*
 	 * The following fields are used by the ASL compiler and disassembler only
@@ -199,7 +200,7 @@ struct acpi_namespace_node {
 
 /* Namespace Node flags */
 
-#define ANOBJ_END_OF_PEER_LIST          0x01	/* End-of-list, Peer field points to parent */
+#define ANOBJ_RESERVED                  0x01	/* Available for use */
 #define ANOBJ_TEMPORARY                 0x02	/* Node is create by a method and is temporary */
 #define ANOBJ_METHOD_ARG                0x04	/* Node is a method argument */
 #define ANOBJ_METHOD_LOCAL              0x08	/* Node is a method local */
drivers/acpi/acpica/acnamesp.h +0 -7
index 258159c..9f60ff0 100644
@@ -369,11 +369,4 @@ struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle);
 
 void acpi_ns_terminate(void);
 
-struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node
-						    *node);
-
-struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct
-							acpi_namespace_node
-							*node);
-
 #endif				/* __ACNAMESP_H__ */
drivers/acpi/acpica/dsmthdat.c +2 -4
index d5e927f..8095306 100644
@@ -102,8 +102,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
 		walk_state->arguments[i].name.integer |= (i << 24);
 		walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED;
 		walk_state->arguments[i].type = ACPI_TYPE_ANY;
-		walk_state->arguments[i].flags =
-		    ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
+		walk_state->arguments[i].flags = ANOBJ_METHOD_ARG;
 	}
 
 	/* Init the method locals */
@@ -116,8 +115,7 @@ void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
 		walk_state->local_variables[i].descriptor_type =
 		    ACPI_DESC_TYPE_NAMED;
 		walk_state->local_variables[i].type = ACPI_TYPE_ANY;
-		walk_state->local_variables[i].flags =
-		    ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
+		walk_state->local_variables[i].flags = ANOBJ_METHOD_LOCAL;
 	}
 
 	return_VOID;
drivers/acpi/acpica/dsopcode.c +3 -3
index 53a7e41..7c0e742 100644
@@ -213,7 +213,7 @@ acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
 
 	/* Execute the AML code for the term_arg arguments */
 
-	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
+	status = acpi_ds_execute_arguments(node, node->parent,
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
 	return_ACPI_STATUS(status);
@@ -257,7 +257,7 @@ acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
 
 	/* Execute the AML code for the term_arg arguments */
 
-	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
+	status = acpi_ds_execute_arguments(node, node->parent,
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
 	return_ACPI_STATUS(status);
@@ -394,7 +394,7 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
 
 	/* Execute the argument AML */
 
-	status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
+	status = acpi_ds_execute_arguments(node, node->parent,
 					   extra_desc->extra.aml_length,
 					   extra_desc->extra.aml_start);
 	if (ACPI_FAILURE(status)) {
drivers/acpi/acpica/evrgnini.c +5 -5
index 2e3b033..f40d271 100644
@@ -199,7 +199,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 		return_ACPI_STATUS(status);
 	}
 
-	parent_node = acpi_ns_get_parent_node(region_obj->region.node);
+	parent_node = region_obj->region.node->parent;
 
 	/*
 	 * Get the _SEG and _BBN values from the device upon which the handler
@@ -248,7 +248,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 				break;
 			}
 
-			pci_root_node = acpi_ns_get_parent_node(pci_root_node);
+			pci_root_node = pci_root_node->parent;
 		}
 
 		/* PCI root bridge not found, use namespace root node */
@@ -280,7 +280,7 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
 	 */
 	pci_device_node = region_obj->region.node;
 	while (pci_device_node && (pci_device_node->type != ACPI_TYPE_DEVICE)) {
-		pci_device_node = acpi_ns_get_parent_node(pci_device_node);
+		pci_device_node = pci_device_node->parent;
 	}
 
 	if (!pci_device_node) {
@@ -521,7 +521,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	node = acpi_ns_get_parent_node(region_obj->region.node);
+	node = region_obj->region.node->parent;
 	space_id = region_obj->region.space_id;
 
 	/* Setup defaults */
@@ -654,7 +654,7 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
 
 		/* This node does not have the handler we need; Pop up one level */
 
-		node = acpi_ns_get_parent_node(node);
+		node = node->parent;
 	}
 
 	/* If we get here, there is no handler for this region */
drivers/acpi/acpica/exdump.c +1 -1
index cdb66d1..f067bbb 100644
@@ -812,7 +812,7 @@ void acpi_ex_dump_namespace_node(struct acpi_namespace_node *node, u32 flags)
 	acpi_ex_out_string("Type", acpi_ut_get_type_name(node->type));
 	acpi_ex_out_pointer("Attached Object",
 			    acpi_ns_get_attached_object(node));
-	acpi_ex_out_pointer("Parent", acpi_ns_get_parent_node(node));
+	acpi_ex_out_pointer("Parent", node->parent);
 
 	acpi_ex_dump_object(ACPI_CAST_PTR(union acpi_operand_object, node),
 			    acpi_ex_dump_node);
drivers/acpi/acpica/nsaccess.c +2 -3
index 2cebfa9..0cd925b 100644
@@ -338,8 +338,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
 			 */
 			while (!acpi_ns_opens_scope(prefix_node->type) &&
 			       prefix_node->type != ACPI_TYPE_ANY) {
-				prefix_node =
-				    acpi_ns_get_parent_node(prefix_node);
+				prefix_node = prefix_node->parent;
 			}
 		}
 	}
@@ -419,7 +418,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
 				/* Backup to the parent node */
 
 				num_carats++;
-				this_node = acpi_ns_get_parent_node(this_node);
+				this_node = this_node->parent;
 				if (!this_node) {
 
 					/* Current scope has no parent scope */
drivers/acpi/acpica/nsalloc.c +25 -49

144 lines not on this page · raw message

drivers/acpi/acpica/nsinit.c +2 -2
index f0e49df..660a272 100644
@@ -410,7 +410,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle,
 	 * The only _INI methods that we care about are those that are
 	 * present under Device, Processor, and Thermal objects.
 	 */
-	parent_node = acpi_ns_get_parent_node(node);
+	parent_node = node->parent;
 	switch (parent_node->type) {
 	case ACPI_TYPE_DEVICE:
 	case ACPI_TYPE_PROCESSOR:
@@ -420,7 +420,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle,
 
 		while (parent_node) {
 			parent_node->flags |= ANOBJ_SUBTREE_HAS_INI;
-			parent_node = acpi_ns_get_parent_node(parent_node);
+			parent_node = parent_node->parent;
 		}
 		break;
 
drivers/acpi/acpica/nsnames.c +2 -2
index 7dea003..d3104af 100644
@@ -93,7 +93,7 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node,
 		/* Put the name into the buffer */
 
 		ACPI_MOVE_32_TO_32((name_buffer + index), &parent_node->name);
-		parent_node = acpi_ns_get_parent_node(parent_node);
+		parent_node = parent_node->parent;
 
 		/* Prefix name with the path separator */
 
@@ -198,7 +198,7 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
 			return 0;
 		}
 		size += ACPI_PATH_SEGMENT_LENGTH;
-		next_node = acpi_ns_get_parent_node(next_node);
+		next_node = next_node->parent;
 	}
 
 	if (!size) {
drivers/acpi/acpica/nssearch.c +2 -13
index a8e42b5..41102a8 100644
@@ -152,17 +152,6 @@ acpi_ns_search_one_scope(u32 target_name,
 			return_ACPI_STATUS(AE_OK);
 		}
 
-		/*
-		 * The last entry in the list points back to the parent,
-		 * so a flag is used to indicate the end-of-list
-		 */
-		if (node->flags & ANOBJ_END_OF_PEER_LIST) {
-
-			/* Searched entire list, we are done */
-
-			break;
-		}
-
 		/* Didn't match name, move on to the next peer object */
 
 		node = node->peer;
@@ -217,7 +206,7 @@ acpi_ns_search_parent_tree(u32 target_name,
 
 	ACPI_FUNCTION_TRACE(ns_search_parent_tree);
 
-	parent_node = acpi_ns_get_parent_node(node);
+	parent_node = node->parent;
 
 	/*
 	 * If there is no parent (i.e., we are at the root) or type is "local",
@@ -261,7 +250,7 @@ acpi_ns_search_parent_tree(u32 target_name,
 
 		/* Not found here, go up another level (until we reach the root) */
 
-		parent_node = acpi_ns_get_parent_node(parent_node);
+		parent_node = parent_node->parent;
 	}
 
 	/* Not found in parent tree */
drivers/acpi/acpica/nsutils.c +0 -113

116 lines not on this page · raw message

drivers/acpi/acpica/nswalk.c +3 -12
index 00e79fb..2cd5be8 100644
@@ -79,15 +79,6 @@ struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
 		return parent_node->child;
 	}
 
-	/*
-	 * Get the next node.
-	 *
-	 * If we are at the end of this peer list, return NULL
-	 */
-	if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
-		return NULL;
-	}
-
 	/* Otherwise just return the next peer */
 
 	return child_node->peer;
@@ -146,9 +137,9 @@ struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
 			return (next_node);
 		}
 
-		/* Otherwise, move on to the next node */
+		/* Otherwise, move on to the next peer node */
 
-		next_node = acpi_ns_get_next_valid_node(next_node);
+		next_node = next_node->peer;
 	}
 
 	/* Not found */
@@ -355,7 +346,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
 			 */
 			level--;
 			child_node = parent_node;
-			parent_node = acpi_ns_get_parent_node(parent_node);
+			parent_node = parent_node->parent;
 
 			node_previously_visited = TRUE;
 		}
drivers/acpi/acpica/nsxfobj.c +1 -1
index eafef24..a1f04e9 100644
@@ -190,7 +190,7 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
 
 	/* Get the parent entry */
 
-	parent_node = acpi_ns_get_parent_node(node);
+	parent_node = node->parent;
 	*ret_handle = ACPI_CAST_PTR(acpi_handle, parent_node);
 
 	/* Return exception if parent is null */
drivers/acpi/acpica/utglobal.c +1 -1
index 6611675..0558747 100644
@@ -813,10 +813,10 @@ acpi_status acpi_ut_init_globals(void)
 	acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
 	acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
 	acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
+	acpi_gbl_root_node_struct.parent = NULL;
 	acpi_gbl_root_node_struct.child = NULL;
 	acpi_gbl_root_node_struct.peer = NULL;
 	acpi_gbl_root_node_struct.object = NULL;
-	acpi_gbl_root_node_struct.flags = ANOBJ_END_OF_PEER_LIST;
 
 #ifdef ACPI_DEBUG_OUTPUT
 	acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
Signature · 1 line
1.6.0.6
author reviewer
#11 lore raw

PATCH 11/16 ACPICA: Update flags for operand object

In reply to Len Brown

From: Bob Moore <[email protected]>

Remove obsolete AOPOBJ_SINGLE_DATUM. Add AOPOBJ_INVALID for use if the host OS rejects the address of an operation region (currently only used by Linux.)

---
 drivers/acpi/acpica/acobject.h |   16 ++++++++--------
 drivers/acpi/acpica/exprep.c   |    9 ---------
 2 files changed, 8 insertions(+), 17 deletions(-)
drivers/acpi/acpica/acobject.h +8 -8
index cde18ea..54857fa 100644
@@ -91,14 +91,14 @@
 
 /* Values for Flag byte above */
 
-#define AOPOBJ_AML_CONSTANT         0x01
-#define AOPOBJ_STATIC_POINTER       0x02
-#define AOPOBJ_DATA_VALID           0x04
-#define AOPOBJ_OBJECT_INITIALIZED   0x08
-#define AOPOBJ_SETUP_COMPLETE       0x10
-#define AOPOBJ_SINGLE_DATUM         0x20
-#define AOPOBJ_INVALID              0x40	/* Used if host OS won't allow an op_region address */
-#define AOPOBJ_MODULE_LEVEL         0x80
+#define AOPOBJ_AML_CONSTANT         0x01	/* Integer is an AML constant */
+#define AOPOBJ_STATIC_POINTER       0x02	/* Data is part of an ACPI table, don't delete */
+#define AOPOBJ_DATA_VALID           0x04	/* Object is intialized and data is valid */
+#define AOPOBJ_OBJECT_INITIALIZED   0x08	/* Region is initialized, _REG was run */
+#define AOPOBJ_SETUP_COMPLETE       0x10	/* Region setup is complete */
+#define AOPOBJ_INVALID              0x20	/* Host OS won't allow a Region address */
+#define AOPOBJ_MODULE_LEVEL         0x40	/* Method is actually module-level code */
+#define AOPOBJ_MODIFIED_NAMESPACE   0x80	/* Method modified the namespace */
 
 /******************************************************************************
  *
drivers/acpi/acpica/exprep.c +0 -9
index 0686f27..98a331d 100644
@@ -385,15 +385,6 @@ acpi_ex_prep_common_field_object(union acpi_operand_object *obj_desc,
 	    (field_bit_position -
 	     ACPI_MUL_8(obj_desc->common_field.base_byte_offset));
 
-	/*
-	 * Does the entire field fit within a single field access element? (datum)
-	 * (i.e., without crossing a datum boundary)
-	 */
-	if ((obj_desc->common_field.start_field_bit_offset +
-	     field_bit_length) <= (u16) access_bit_width) {
-		obj_desc->common.flags |= AOPOBJ_SINGLE_DATUM;
-	}
-
 	return_ACPI_STATUS(AE_OK);
 }
 
Signature · 1 line
1.6.0.6
author reviewer
#12 lore raw

PATCH 12/16 ACPICA: Optimization: Reduce the number of namespace walks

In reply to Len Brown

From: Alexey Starikovskiy <[email protected]>

On control method exit, only walk the namespace if the method is known to have created namespace objects outside of its local scope.

---
 drivers/acpi/acpica/dsmethod.c |   18 ++++++++++++++++--
 drivers/acpi/acpica/nsalloc.c  |   20 ++++++++++++++++----
 2 files changed, 32 insertions(+), 6 deletions(-)
drivers/acpi/acpica/dsmethod.c +16 -2
index 0084633..64750ee 100644
@@ -584,8 +584,22 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
 		 * want make the objects permanent.
 		 */
 		if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) {
-			acpi_ns_delete_namespace_by_owner(method_desc->method.
-							  owner_id);
+
+			/* Delete any direct children of (created by) this method */
+
+			acpi_ns_delete_namespace_subtree(walk_state->
+							 method_node);
+
+			/*
+			 * Delete any objects that were created by this method
+			 * elsewhere in the namespace (if any were created).
+			 */
+			if (method_desc->method.
+			    flags & AOPOBJ_MODIFIED_NAMESPACE) {
+				acpi_ns_delete_namespace_by_owner(method_desc->
+								  method.
+								  owner_id);
+			}
 		}
 	}
 
drivers/acpi/acpica/nsalloc.c +16 -4
index 8d3a43a..1e5ff80 100644
@@ -219,12 +219,24 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
 
 	ACPI_FUNCTION_TRACE(ns_install_node);
 
-	/*
-	 * Get the owner ID from the Walk state. The owner ID is used to track
-	 * table deletion and deletion of objects created by methods.
-	 */
 	if (walk_state) {
+		/*
+		 * Get the owner ID from the Walk state. The owner ID is used to
+		 * track table deletion and deletion of objects created by methods.
+		 */
 		owner_id = walk_state->owner_id;
+
+		if ((walk_state->method_desc) &&
+		    (parent_node != walk_state->method_node)) {
+			/*
+			 * A method is creating a new node that is not a child of the
+			 * method (it is non-local). Mark the executing method as having
+			 * modified the namespace. This is used for cleanup when the
+			 * method exits.
+			 */
+			walk_state->method_desc->method.flags |=
+			    AOPOBJ_MODIFIED_NAMESPACE;
+		}
 	}
 
 	/* Link the new entry into the parent and existing children */
Signature · 1 line
1.6.0.6
author reviewer
#13 lore raw

PATCH 13/16 ACPICA: Add signatures for undefined tables: ATKG, GSCI, IEIT

In reply to Len Brown

From: Bob Moore <[email protected]>

These ACPI tables have been seen in the field, but the actual table definitions are unkown at this time.

---
 include/acpi/actbl2.h |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
include/acpi/actbl2.h +9 -0
index 95f4d0e..0a600b8 100644
@@ -79,6 +79,15 @@
 #define ACPI_SIG_WDAT           "WDAT"	/* Watchdog Action Table */
 #define ACPI_SIG_WDRT           "WDRT"	/* Watchdog Resource Table */
 
+#ifdef ACPI_UNDEFINED_TABLES
+/*
+ * These tables have been seen in the field, but no definition has been found
+ */
+#define ACPI_SIG_ATKG           "ATKG"
+#define ACPI_SIG_GSCI           "GSCI"	/* GMCH SCI table */
+#define ACPI_SIG_IEIT           "IEIT"
+#endif
+
 /*
  * All tables must be byte-packed to match the ACPI specification, since
  * the tables are provided by the system BIOS.
Signature · 1 line
1.6.0.6
author reviewer
#14 lore raw

PATCH 14/16 ACPICA: Update version to 20100528

In reply to Len Brown

From: Bob Moore <[email protected]>

Version 20100528.

---
 include/acpi/acpixf.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
include/acpi/acpixf.h +1 -1
index 1371cc9..8aaa596 100644
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20100428
+#define ACPI_CA_VERSION                 0x20100528
 
 #include "actypes.h"
 #include "actbl.h"
Signature · 1 line
1.6.0.6
author reviewer
#15 lore raw

PATCH 15/16 suspend: Move NVS save/restore code to generic suspend functionality

In reply to Len Brown

From: Matthew Garrett <[email protected]>

Saving platform non-volatile state may be required for suspend to RAM as well as hibernation. Move it to more generic code.

---
 arch/x86/kernel/e820.c       |    2 +-
 drivers/acpi/sleep.c         |   12 ++--
 include/linux/suspend.h      |   26 ++++----
 kernel/power/Kconfig         |    9 ++-
 kernel/power/Makefile        |    2 +-
 kernel/power/hibernate_nvs.c |  136 ------------------------------------------
 kernel/power/nvs.c           |  136 ++++++++++++++++++++++++++++++++++++++++++
 kernel/power/suspend.c       |    6 ++
 8 files changed, 168 insertions(+), 161 deletions(-)
 delete mode 100644 kernel/power/hibernate_nvs.c
 create mode 100644 kernel/power/nvs.c
arch/x86/kernel/e820.c +1 -1
index 7bca3c6..0d6fc71 100644
@@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void)
 		struct e820entry *ei = &e820.map[i];
 
 		if (ei->type == E820_NVS)
-			hibernate_nvs_register(ei->addr, ei->size);
+			suspend_nvs_register(ei->addr, ei->size);
 	}
 
 	return 0;
drivers/acpi/sleep.c +6 -6
index 4ab2275..bcaa6ef 100644
@@ -393,7 +393,7 @@ static int acpi_hibernation_begin(void)
 {
 	int error;
 
-	error = s4_no_nvs ? 0 : hibernate_nvs_alloc();
+	error = s4_no_nvs ? 0 : suspend_nvs_alloc();
 	if (!error) {
 		acpi_target_sleep_state = ACPI_STATE_S4;
 		acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -407,7 +407,7 @@ static int acpi_hibernation_pre_snapshot(void)
 	int error = acpi_pm_prepare();
 
 	if (!error)
-		hibernate_nvs_save();
+		suspend_nvs_save();
 
 	return error;
 }
@@ -432,7 +432,7 @@ static int acpi_hibernation_enter(void)
 
 static void acpi_hibernation_finish(void)
 {
-	hibernate_nvs_free();
+	suspend_nvs_free();
 	acpi_pm_finish();
 }
 
@@ -452,7 +452,7 @@ static void acpi_hibernation_leave(void)
 		panic("ACPI S4 hardware signature mismatch");
 	}
 	/* Restore the NVS memory area */
-	hibernate_nvs_restore();
+	suspend_nvs_restore();
 }
 
 static int acpi_pm_pre_restore(void)
@@ -501,7 +501,7 @@ static int acpi_hibernation_begin_old(void)
 
 	if (!error) {
 		if (!s4_no_nvs)
-			error = hibernate_nvs_alloc();
+			error = suspend_nvs_alloc();
 		if (!error)
 			acpi_target_sleep_state = ACPI_STATE_S4;
 	}
@@ -513,7 +513,7 @@ static int acpi_hibernation_pre_snapshot_old(void)
 	int error = acpi_pm_disable_gpes();
 
 	if (!error)
-		hibernate_nvs_save();
+		suspend_nvs_save();
 
 	return error;
 }
include/linux/suspend.h +13 -13
index 5e781d8..bc7d6bb 100644
@@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; }
 static inline bool system_entering_hibernation(void) { return false; }
 #endif /* CONFIG_HIBERNATION */
 
-#ifdef CONFIG_HIBERNATION_NVS
-extern int hibernate_nvs_register(unsigned long start, unsigned long size);
-extern int hibernate_nvs_alloc(void);
-extern void hibernate_nvs_free(void);
-extern void hibernate_nvs_save(void);
-extern void hibernate_nvs_restore(void);
-#else /* CONFIG_HIBERNATION_NVS */
-static inline int hibernate_nvs_register(unsigned long a, unsigned long b)
+#ifdef CONFIG_SUSPEND_NVS
+extern int suspend_nvs_register(unsigned long start, unsigned long size);
+extern int suspend_nvs_alloc(void);
+extern void suspend_nvs_free(void);
+extern void suspend_nvs_save(void);
+extern void suspend_nvs_restore(void);
+#else /* CONFIG_SUSPEND_NVS */
+static inline int suspend_nvs_register(unsigned long a, unsigned long b)
 {
 	return 0;
 }
-static inline int hibernate_nvs_alloc(void) { return 0; }
-static inline void hibernate_nvs_free(void) {}
-static inline void hibernate_nvs_save(void) {}
-static inline void hibernate_nvs_restore(void) {}
-#endif /* CONFIG_HIBERNATION_NVS */
+static inline int suspend_nvs_alloc(void) { return 0; }
+static inline void suspend_nvs_free(void) {}
+static inline void suspend_nvs_save(void) {}
+static inline void suspend_nvs_restore(void) {}
+#endif /* CONFIG_SUSPEND_NVS */
 
 #ifdef CONFIG_PM_SLEEP
 void save_processor_state(void);
kernel/power/Kconfig +5 -4
index 5c36ea9..ca6066a 100644
@@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG
 	depends on PM_ADVANCED_DEBUG
 	default n
 
+config SUSPEND_NVS
+       bool
+
 config SUSPEND
 	bool "Suspend to RAM and standby"
 	depends on PM && ARCH_SUSPEND_POSSIBLE
+	select SUSPEND_NVS if HAS_IOMEM
 	default y
 	---help---
 	  Allow the system to enter sleep states in which main memory is
@@ -130,13 +134,10 @@ config SUSPEND_FREEZER
 
 	  Turning OFF this setting is NOT recommended! If in doubt, say Y.
 
-config HIBERNATION_NVS
-	bool
-
 config HIBERNATION
 	bool "Hibernation (aka 'suspend to disk')"
 	depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
-	select HIBERNATION_NVS if HAS_IOMEM
+	select SUSPEND_NVS if HAS_IOMEM
 	---help---
 	  Enable the suspend to disk (STD) functionality, which is usually
 	  called "hibernation" in user interfaces.  STD checkpoints the
kernel/power/Makefile +1 -1
index 524e058..f9063c6 100644
@@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND)		+= suspend.o
 obj-$(CONFIG_PM_TEST_SUSPEND)	+= suspend_test.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o snapshot.o swap.o user.o \
 				   block_io.o
-obj-$(CONFIG_HIBERNATION_NVS)	+= hibernate_nvs.o
+obj-$(CONFIG_SUSPEND_NVS)	+= nvs.o
 
 obj-$(CONFIG_MAGIC_SYSRQ)	+= poweroff.o
kernel/power/hibernate_nvs.c deleted +0 -136

136 lines not on this page · raw message

kernel/power/nvs.c new file +136 -0

136 lines not on this page · raw message

kernel/power/suspend.c +6 -0
index 56e7dbb..f37cb7d 100644
@@ -16,6 +16,12 @@
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
 #include <linux/gfp.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
 
 #include "power.h"
 
Signature · 1 line
1.6.0.6
author reviewer
#16 lore raw

PATCH 16/16 ACPI: Store NVS state even when entering suspend to RAM

In reply to Len Brown

From: Matthew Garrett <[email protected]>

https://bugzilla.kernel.org/show_bug.cgi?id=13931 describes a bug where a system fails to successfully resume after the second suspend. Maxim Levitsky discovered that this could be rectified by forcibly saving and restoring the ACPI non-volatile state. The spec indicates that this is only required for S4, but testing the behaviour of Windows by adding an ACPI NVS region to qemu's e820 map and registering a custom memory read/write handler reveals that it's saved and restored even over suspend to RAM. We should mimic that behaviour to avoid other broken platforms.

---
 drivers/acpi/sleep.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)
drivers/acpi/sleep.c +13 -8
index bcaa6ef..403daf0 100644
@@ -112,6 +112,8 @@ static int __acpi_pm_prepare(void)
 {
 	int error = acpi_sleep_prepare(acpi_target_sleep_state);
 
+	suspend_nvs_save();
+
 	if (error)
 		acpi_target_sleep_state = ACPI_STATE_S0;
 	return error;
@@ -140,6 +142,8 @@ static void acpi_pm_finish(void)
 {
 	u32 acpi_state = acpi_target_sleep_state;
 
+	suspend_nvs_free();
+
 	if (acpi_state == ACPI_STATE_S0)
 		return;
 
@@ -189,6 +193,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state)
 	u32 acpi_state = acpi_suspend_states[pm_state];
 	int error = 0;
 
+	error = suspend_nvs_alloc();
+
+	if (error)
+		return error;
+
 	if (sleep_states[acpi_state]) {
 		acpi_target_sleep_state = acpi_state;
 		acpi_sleep_tts_switch(acpi_target_sleep_state);
@@ -264,6 +273,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
 	if (acpi_state == ACPI_STATE_S3)
 		acpi_restore_state_mem();
 
+	suspend_nvs_restore();
+
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
@@ -430,12 +441,6 @@ static int acpi_hibernation_enter(void)
 	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 }
 
-static void acpi_hibernation_finish(void)
-{
-	suspend_nvs_free();
-	acpi_pm_finish();
-}
-
 static void acpi_hibernation_leave(void)
 {
 	/*
@@ -473,7 +478,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops = {
 	.begin = acpi_hibernation_begin,
 	.end = acpi_pm_end,
 	.pre_snapshot = acpi_hibernation_pre_snapshot,
-	.finish = acpi_hibernation_finish,
+	.finish = acpi_pm_finish,
 	.prepare = acpi_pm_prepare,
 	.enter = acpi_hibernation_enter,
 	.leave = acpi_hibernation_leave,
@@ -526,7 +531,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = {
 	.begin = acpi_hibernation_begin_old,
 	.end = acpi_pm_end,
 	.pre_snapshot = acpi_hibernation_pre_snapshot_old,
-	.finish = acpi_hibernation_finish,
+	.finish = acpi_pm_finish,
 	.prepare = acpi_pm_disable_gpes,
 	.enter = acpi_hibernation_enter,
 	.leave = acpi_hibernation_leave,
Signature · 1 line
1.6.0.6