#ifdef CONFIG_HOTPLUG_CPU /* * Check for P_LVL2_UP flag before entering C2 and above on * an SMP system. We do it here instead of doing it at _CST/P_LVL * detection phase, to work cleanly with logical CPU hotplug. */ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && !pr->flags.has_cst && acpi_fadt.plvl2_up) cx->type = ACPI_STATE_C1; #endif 
static void acpi_processor_idle(void){	struct acpi_processor *pr = NULL;	struct acpi_processor_cx *cx = NULL;	struct acpi_processor_cx *next_state = NULL;	int sleep_ticks = 0;	u32 t1, t2 = 0;	pr = processors[smp_processor_id()];	if (!pr)		return;	/*	 * Interrupts must be disabled during bus mastering calculations and	 * for C2/C3 transitions.	 */	local_irq_disable();	/*	 * Check whether we truly need to go idle, or should	 * reschedule:	 */	if (unlikely(need_resched())) {		local_irq_enable();		return;	}	cx = pr->power.state;	if (!cx) {		if (pm_idle_save)			pm_idle_save();		else			acpi_safe_halt();		return;	}	/*	 * Check BM Activity	 * -----------------	 * Check for bus mastering activity (if required), record, and check	 * for demotion.	 */	if (pr->flags.bm_check) {		u32 bm_status = 0;		unsigned long diff = jiffies - pr->power.bm_check_timestamp;		if (diff > 32)			diff = 32;		while (diff) {			/* if we didn't get called, assume there was busmaster activity */			diff--;			if (diff)				pr->power.bm_activity |= 0x1;			pr->power.bm_activity <<= 1;		}		acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,				  &bm_status, ACPI_MTX_DO_NOT_LOCK);		if (bm_status) {			pr->power.bm_activity++;			acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,					  1, ACPI_MTX_DO_NOT_LOCK);		}		/*		 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect		 * the true state of bus mastering activity; forcing us to		 * manually check the BMIDEA bit of each IDE channel.		 */		else if (errata.piix4.bmisx) {			if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)			    || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))				pr->power.bm_activity++;		}		pr->power.bm_check_timestamp = jiffies;		/*		 * Apply bus mastering demotion policy.  Automatically demote		 * to avoid a faulty transition.  Note that the processor		 * won't enter a low-power state during this call (to this		 * funciton) but should upon the next.		 *		 * TBD: A better policy might be to fallback to the demotion		 *      state (use it for this quantum only) istead of		 *      demoting -- and rely on duration as our sole demotion		 *      qualification.  This may, however, introduce DMA		 *      issues (e.g. floppy DMA transfer overrun/underrun).		 */		if (pr->power.bm_activity & cx->demotion.threshold.bm) {			local_irq_enable();			next_state = cx->demotion.state;			goto end;		}	}	cx->usage++;	/*	 * Sleep:	 * ------	 * Invoke the current Cx state to put the processor to sleep.	 */	switch (cx->type) {	case ACPI_STATE_C1:		/*		 * Invoke C1.		 * Use the appropriate idle routine, the one that would		 * be used without acpi C-states.		 */		if (pm_idle_save)			pm_idle_save();		else			acpi_safe_halt();		/*		 * TBD: Can't get time duration while in C1, as resumes		 *      go to an ISR rather than here.  Need to instrument		 *      base interrupt handler.		 */		sleep_ticks = 0xFFFFFFFF;		break;	case ACPI_STATE_C2:		/* Get start time (ticks) */		t1 = inl(acpi_fadt.xpm_tmr_blk.address);		/* Invoke C2 */		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) */		t2 = inl(acpi_fadt.xpm_tmr_blk.address);		/* Re-enable interrupts */		local_irq_enable();		/* Compute time (ticks) that we were actually asleep */		sleep_ticks =		    ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;		break;	case ACPI_STATE_C3:		if (pr->flags.bm_check) {			if (atomic_inc_return(&c3_cpu_count) ==			    num_online_cpus()) {				/*				 * All CPUs are trying to go to C3				 * Disable bus master arbitration				 */				acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1,						  ACPI_MTX_DO_NOT_LOCK);			}		} else {			/* SMP with no shared cache... Invalidate cache  */			ACPI_FLUSH_CPU_CACHE();		}		/* Get start time (ticks) */		t1 = inl(acpi_fadt.xpm_tmr_blk.address);		/* Invoke C3 */		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) */		t2 = inl(acpi_fadt.xpm_tmr_blk.address);		if (pr->flags.bm_check) {			/* Enable bus master arbitration */			atomic_dec(&c3_cpu_count);			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0,					  ACPI_MTX_DO_NOT_LOCK);		}		/* Re-enable interrupts */		local_irq_enable();		/* Compute time (ticks) that we were actually asleep */		sleep_ticks =		    ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;		break;	default:		local_irq_enable();		return;	}	next_state = pr->power.state;	/*	 * Promotion?	 * ----------	 * Track the number of longs (time asleep is greater than threshold)	 * and promote when the count threshold is reached.  Note that bus	 * mastering activity may prevent promotions.	 * Do not promote above max_cstate.	 */	if (cx->promotion.state &&	    ((cx->promotion.state - pr->power.states) <= max_cstate)) {		if (sleep_ticks > cx->promotion.threshold.ticks) {			cx->promotion.count++;			cx->demotion.count = 0;			if (cx->promotion.count >=			    cx->promotion.threshold.count) {				if (pr->flags.bm_check) {					if (!					    (pr->power.bm_activity & cx->					     promotion.threshold.bm)) {						next_state =						    cx->promotion.state;						goto end;					}				} else {					next_state = cx->promotion.state;					goto end;				}			}		}	}	/*	 * Demotion?	 * ---------	 * Track the number of shorts (time asleep is less than time threshold)	 * and demote when the usage threshold is reached.	 */	if (cx->demotion.state) {		if (sleep_ticks < cx->demotion.threshold.ticks) {			cx->demotion.count++;			cx->promotion.count = 0;			if (cx->demotion.count >= cx->demotion.threshold.count) {				next_state = cx->demotion.state;				goto end;			}		}	}      end:	/*	 * Demote if current state exceeds max_cstate	 */	if ((pr->power.state - pr->power.states) > max_cstate) {		if (cx->demotion.state)			next_state = cx->demotion.state;	}	/*	 * New Cx State?	 * -------------	 * 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)		acpi_processor_power_activate(pr, next_state);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/4c0335526c95d90a1d958e0059f40a5745fc7c5d/processor_idle.c/clean/drivers/acpi/processor_idle.c