It's important to make a difference between the actual C-States and the _type_ of the C-State. While they're always equal for ACPI 1.0 systems, they can differ for ACPI 2.0 or later systems. Therefore, use _type_ wherever appropriate. Signed-off-by: Dominik Broodwski 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 18:54:16.557873688 +0100 +++ linux/drivers/acpi/processor_idle.c 2004-11-27 18:54:42.385947224 +0100 @@ -97,25 +97,32 @@ struct acpi_processor *pr, int state) { + struct acpi_processor_cx *old, *new; + if (!pr) return; - pr->power.states[pr->power.state].promotion.count = 0; - pr->power.states[pr->power.state].demotion.count = 0; + old = &pr->power.states[pr->power.state]; + new = &pr->power.states[state]; + + old->promotion.count = 0; + new->demotion.count = 0; /* Cleanup from old state. */ - switch (pr->power.state) { + switch (old->type) { case ACPI_STATE_C3: /* Disable bus master reload */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0, ACPI_MTX_DO_NOT_LOCK); + 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. */ - switch (state) { + switch (new->type) { case ACPI_STATE_C3: /* Enable bus master reload */ - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK); + if (old->type != ACPI_STATE_C3) + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1, ACPI_MTX_DO_NOT_LOCK); break; } @@ -199,7 +206,7 @@ * ------ * Invoke the current Cx state to put the processor to sleep. */ - switch (pr->power.state) { + switch (cx->type) { case ACPI_STATE_C1: /* @@ -223,7 +230,7 @@ /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C2 */ - inb(pr->power.states[ACPI_STATE_C2].address); + inb(cx->address); /* Dummy op - must do something useless after P_LVL2 read */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Get end time (ticks) */ @@ -240,7 +247,7 @@ /* Get start time (ticks) */ t1 = inl(acpi_fadt.xpm_tmr_blk.address); /* Invoke C3 */ - inb(pr->power.states[ACPI_STATE_C3].address); + inb(cx->address); /* Dummy op - must do something useless after P_LVL3 read */ t2 = inl(acpi_fadt.xpm_tmr_blk.address); /* Get end time (ticks) */ @@ -437,6 +444,7 @@ * TBD: What about PROC_C1? */ pr->power.states[ACPI_STATE_C1].valid = 1; + pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1; /* * C2 @@ -473,6 +481,7 @@ */ else { pr->power.states[ACPI_STATE_C2].valid = 1; + pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2; pr->power.states[ACPI_STATE_C2].latency_ticks = US_TO_PM_TIMER_TICKS(acpi_fadt.plvl2_lat); } @@ -533,6 +542,7 @@ */ else { pr->power.states[ACPI_STATE_C3].valid = 1; + pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; pr->power.states[ACPI_STATE_C3].latency_ticks = US_TO_PM_TIMER_TICKS(acpi_fadt.plvl3_lat); pr->flags.bm_check = 1; @@ -576,8 +586,8 @@ if (!pr) goto end; - seq_printf(seq, "active state: C%d\n" - "default state: C%d\n" + seq_printf(seq, "active state: %d\n" + "default state: %d\n" "bus master activity: %08x\n", pr->power.state, pr->power.default_state, @@ -586,7 +596,7 @@ seq_puts(seq, "states:\n"); for (i = 1; i < ACPI_C_STATE_COUNT; i++) { - seq_printf(seq, " %cC%d: ", + seq_printf(seq, " %c%d: ", (i == pr->power.state?'*':' '), i); if (!pr->power.states[i].valid) { @@ -594,17 +604,32 @@ continue; } + switch (pr->power.states[i].type) { + case ACPI_STATE_C1: + seq_printf(seq, "type[C1] "); + break; + case ACPI_STATE_C2: + seq_printf(seq, "type[C2] "); + break; + case ACPI_STATE_C3: + seq_printf(seq, "type[C3] "); + break; + default: + seq_printf(seq, "type[--] "); + break; + } + if (pr->power.states[i].promotion.state) - seq_printf(seq, "promotion[C%d] ", + seq_printf(seq, "promotion[%d] ", pr->power.states[i].promotion.state); else - seq_puts(seq, "promotion[--] "); + seq_puts(seq, "promotion[-] "); if (pr->power.states[i].demotion.state) - seq_printf(seq, "demotion[C%d] ", + seq_printf(seq, "demotion[%d] ", pr->power.states[i].demotion.state); else - seq_puts(seq, "demotion[--] "); + seq_puts(seq, "demotion[-] "); seq_printf(seq, "latency[%03d] usage[%08d]\n", pr->power.states[i].latency, diff -ruN linux-original/include/acpi/processor.h linux/include/acpi/processor.h --- linux-original/include/acpi/processor.h 2004-11-27 18:54:16.609865784 +0100 +++ linux/include/acpi/processor.h 2004-11-27 18:53:56.221965216 +0100 @@ -29,6 +29,7 @@ struct acpi_processor_cx { u8 valid; + u8 type; u32 address; u32 latency; u32 latency_ticks;