Make the current "state" in struct acpi_processor_power a pointer. If it
doesn't exist, simply use C1 type sleep...

Signed-off-by: Dominik Brodowski

 drivers/acpi/processor_idle.c |   48 +++++++++++++++++++++++++++---------------
 include/acpi/processor.h      |    2 -
 2 files changed, 32 insertions(+), 18 deletions(-)

diff -ruN linux-original/drivers/acpi/processor_idle.c linux/drivers/acpi/processor_idle.c
--- linux-original/drivers/acpi/processor_idle.c	2004-11-27 20:25:24.336644968 +0100
+++ linux/drivers/acpi/processor_idle.c	2004-11-27 20:25:29.620841648 +0100
@@ -102,19 +102,22 @@
 	if (!pr)
 		return;
 
-	old = &pr->power.states[pr->power.state];
+	old = pr->power.state;
 	new = &pr->power.states[state];
 
- 	old->promotion.count = 0;
+	if (old)
+		old->promotion.count = 0;
  	new->demotion.count = 0;
 
 	/* Cleanup from old state. */
-	switch (old->type) {
-	case ACPI_STATE_C3:
-		/* Disable bus master reload */
-		if (new->type != ACPI_STATE_C3)
-			acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
-		break;
+	if (old) {
+		switch (old->type) {
+		case ACPI_STATE_C3:
+			/* Disable bus master reload */
+			if (new->type != ACPI_STATE_C3)
+				acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK);
+			break;
+		}
 	}
 
 	/* Prepare to use new state. */
@@ -126,7 +129,7 @@
 		break;
 	}
 
-	pr->power.state = state;
+	pr->power.state = new;
 
 	return;
 }
@@ -150,7 +153,9 @@
 	 */
 	local_irq_disable();
 
-	cx = &(pr->power.states[pr->power.state]);
+	cx = pr->power.state;
+	if (!cx)
+		goto easy_out;
 
 	/*
 	 * Check BM Activity
@@ -265,7 +270,7 @@
 		return;
 	}
 
-	next_state = pr->power.state;
+	next_state = pr->power.state - pr->power.states;
 
 	/*
 	 * Promotion?
@@ -315,8 +320,9 @@
 	/*
 	 * Demote if current state exceeds acpi_cstate_limit
 	 */
-	if (pr->power.state > acpi_cstate_limit) {
-		next_state = acpi_cstate_limit;
+	if (pr->power.state->type > acpi_cstate_limit) {
+		if (cx->demotion.state)
+			next_state = cx->demotion.state;
 	}
 
 	/*
@@ -325,10 +331,18 @@
 	 * If we're going to start using a new Cx state we must clean up
 	 * from the previous and prepare to use the new.
 	 */
-	if (next_state != pr->power.state)
+	if (&pr->power.states[next_state] != pr->power.state)
 		acpi_processor_power_activate(pr, next_state);
 
 	return;
+
+ easy_out:
+	/* do C1 instead of busy loop */
+	if (pm_idle_save)
+		pm_idle_save();
+	else
+		safe_halt();
+	return;
 }
 
 
@@ -354,7 +368,7 @@
 	 * C0/C1
 	 * -----
 	 */
-	pr->power.state = ACPI_STATE_C1;
+	pr->power.state = &pr->power.states[ACPI_STATE_C1];
 
 	/*
 	 * C1/C2
@@ -637,14 +651,14 @@
 
 	seq_printf(seq, "active state:            %d\n"
 			"bus master activity:     %08x\n",
-			pr->power.state,
+			pr->power.state ? pr->power.state - pr->power.states : 0,
 			pr->power.bm_activity);
 
 	seq_puts(seq, "states:\n");
 
 	for (i = 1; i < ACPI_C_STATE_COUNT; i++) {
 		seq_printf(seq, "   %c%d:                  ",
-			(i == pr->power.state?'*':' '), i);
+			(&pr->power.states[i] == pr->power.state?'*':' '), i);
 
 		if (!pr->power.states[i].valid) {
 			seq_puts(seq, "<not supported>\n");
diff -ruN linux-original/include/acpi/processor.h linux/include/acpi/processor.h
--- linux-original/include/acpi/processor.h	2004-11-27 20:25:24.337644816 +0100
+++ linux/include/acpi/processor.h	2004-11-27 20:25:42.399898936 +0100
@@ -40,7 +40,7 @@
 };
 
 struct acpi_processor_power {
-	int			state;
+	struct acpi_processor_cx *state;
 	u32			bm_activity;
 	struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
 };