1484 lines · 38.0 KB · C
RawDownload
/* * processor_idle - idle state submodule to the ACPI processor driver * *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> *  Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de> *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> *  			- Added processor hotplug support *  Copyright (C) 2005  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> *  			- Added support for C3 on SMP * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or (at *  your option) any later version. * *  This program is distributed in the hope that it will be useful, but *  WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  General Public License for more details. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */#define pr_fmt(fmt) "ACPI: " fmt #include <linux/module.h>#include <linux/acpi.h>#include <linux/dmi.h>#include <linux/sched.h>       /* need_resched() */#include <linux/tick.h>#include <linux/cpuidle.h>#include <linux/cpu.h>#include <acpi/processor.h> /* * Include the apic definitions for x86 to have the APIC timer related defines * available also for UP (on SMP it gets magically included via linux/smp.h). * asm/acpi.h is not an option, as it would require more include magic. Also * creating an empty asm-ia64/apic.h would just trade pest vs. cholera. */#ifdef CONFIG_X86#include <asm/apic.h>#endif #define ACPI_PROCESSOR_CLASS            "processor"#define _COMPONENT              ACPI_PROCESSOR_COMPONENTACPI_MODULE_NAME("processor_idle"); static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;module_param(max_cstate, uint, 0000);static unsigned int nocst __read_mostly;module_param(nocst, uint, 0000);static int bm_check_disable __read_mostly;module_param(bm_check_disable, uint, 0000); static unsigned int latency_factor __read_mostly = 2;module_param(latency_factor, uint, 0644); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); struct cpuidle_driver acpi_idle_driver = {	.name =		"acpi_idle",	.owner =	THIS_MODULE,}; #ifdef CONFIG_ACPI_PROCESSOR_CSTATEstaticDEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate); static int disabled_by_idle_boot_param(void){	return boot_option_idle_override == IDLE_POLL ||		boot_option_idle_override == IDLE_HALT;} /* * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. * For now disable this. Probably a bug somewhere else. * * To skip this limit, boot/load with a large max_cstate limit. */static int set_max_cstate(const struct dmi_system_id *id){	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)		return 0; 	pr_notice("%s detected - limiting to C%ld max_cstate."		  " Override with \"processor.max_cstate=%d\"\n", id->ident,		  (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1); 	max_cstate = (long)id->driver_data; 	return 0;} static const struct dmi_system_id processor_power_dmi_table[] = {	{ set_max_cstate, "Clevo 5600D", {	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},	 (void *)2},	{ set_max_cstate, "Pavilion zv5000", {	  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),	  DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},	 (void *)1},	{ set_max_cstate, "Asus L8400B", {	  DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),	  DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},	 (void *)1},	{},};  /* * Callers should disable interrupts before the call and enable * interrupts after return. */static void __cpuidle acpi_safe_halt(void){	if (!tif_need_resched()) {		safe_halt();		local_irq_disable();	}} #ifdef ARCH_APICTIMER_STOPS_ON_C3 /* * Some BIOS implementations switch to C3 in the published C2 state. * This seems to be a common problem on AMD boxen, but other vendors * are affected too. We pick the most conservative approach: we assume * that the local APIC stops in both C2 and C3. */static void lapic_timer_check_state(int state, struct acpi_processor *pr,				   struct acpi_processor_cx *cx){	struct acpi_processor_power *pwr = &pr->power;	u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2; 	if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))		return; 	if (boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E))		type = ACPI_STATE_C1; 	/*	 * Check, if one of the previous states already marked the lapic	 * unstable	 */	if (pwr->timer_broadcast_on_state < state)		return; 	if (cx->type >= type)		pr->power.timer_broadcast_on_state = state;} static void __lapic_timer_propagate_broadcast(void *arg){	struct acpi_processor *pr = (struct acpi_processor *) arg; 	if (pr->power.timer_broadcast_on_state < INT_MAX)		tick_broadcast_enable();	else		tick_broadcast_disable();} static void lapic_timer_propagate_broadcast(struct acpi_processor *pr){	smp_call_function_single(pr->id, __lapic_timer_propagate_broadcast,				 (void *)pr, 1);} /* Power(C) State timer broadcast control */static void lapic_timer_state_broadcast(struct acpi_processor *pr,				       struct acpi_processor_cx *cx,				       int broadcast){	int state = cx - pr->power.states; 	if (state >= pr->power.timer_broadcast_on_state) {		if (broadcast)			tick_broadcast_enter();		else			tick_broadcast_exit();	}} #else static void lapic_timer_check_state(int state, struct acpi_processor *pr,				   struct acpi_processor_cx *cstate) { }static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }static void lapic_timer_state_broadcast(struct acpi_processor *pr,				       struct acpi_processor_cx *cx,				       int broadcast){} #endif #if defined(CONFIG_X86)static void tsc_check_state(int state){	switch (boot_cpu_data.x86_vendor) {	case X86_VENDOR_AMD:	case X86_VENDOR_INTEL:		/*		 * 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*/	default:		/* TSC could halt in idle, so notify users */		if (state > ACPI_STATE_C1)			mark_tsc_unstable("TSC halts in idle");	}}#elsestatic void tsc_check_state(int state) { return; }#endif static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr){ 	if (!pr->pblk)		return -ENODEV; 	/* if info is obtained from pblk/fadt, type equals state */	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3; #ifndef CONFIG_HOTPLUG_CPU	/*	 * Check for P_LVL2_UP flag before entering C2 and above on	 * an SMP system.	 */	if ((num_online_cpus() > 1) &&	    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))		return -ENODEV;#endif 	/* determine C2 and C3 address from pblk */	pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;	pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5; 	/* determine latencies from FADT */	pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.c2_latency;	pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.c3_latency; 	/*	 * FADT specified C2 latency must be less than or equal to	 * 100 microseconds.	 */	if (acpi_gbl_FADT.c2_latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {		ACPI_DEBUG_PRINT((ACPI_DB_INFO,			"C2 latency too large [%d]\n", acpi_gbl_FADT.c2_latency));		/* invalidate C2 */		pr->power.states[ACPI_STATE_C2].address = 0;	} 	/*	 * FADT supplied C3 latency must be less than or equal to	 * 1000 microseconds.	 */	if (acpi_gbl_FADT.c3_latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {		ACPI_DEBUG_PRINT((ACPI_DB_INFO,			"C3 latency too large [%d]\n", acpi_gbl_FADT.c3_latency));		/* invalidate C3 */		pr->power.states[ACPI_STATE_C3].address = 0;	} 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,			  "lvl2[0x%08x] lvl3[0x%08x]\n",			  pr->power.states[ACPI_STATE_C2].address,			  pr->power.states[ACPI_STATE_C3].address)); 	return 0;} static int acpi_processor_get_power_info_default(struct acpi_processor *pr){	if (!pr->power.states[ACPI_STATE_C1].valid) {		/* set the first C-State to C1 */		/* all processors need to support C1 */		pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;		pr->power.states[ACPI_STATE_C1].valid = 1;		pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;	}	/* the C0 state only exists as a filler in our array */	pr->power.states[ACPI_STATE_C0].valid = 1;	return 0;} static int acpi_processor_get_power_info_cst(struct acpi_processor *pr){	acpi_status status;	u64 count;	int current_count;	int i, ret = 0;	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };	union acpi_object *cst; 	if (nocst)		return -ENODEV; 	current_count = 0; 	status = acpi_evaluate_object(pr->handle, "_CST", NULL, &buffer);	if (ACPI_FAILURE(status)) {		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _CST, giving up\n"));		return -ENODEV;	} 	cst = buffer.pointer; 	/* There must be at least 2 elements */	if (!cst || (cst->type != ACPI_TYPE_PACKAGE) || cst->package.count < 2) {		pr_err("not enough elements in _CST\n");		ret = -EFAULT;		goto end;	} 	count = cst->package.elements[0].integer.value; 	/* Validate number of power states. */	if (count < 1 || count != cst->package.count - 1) {		pr_err("count given by _CST is not valid\n");		ret = -EFAULT;		goto end;	} 	/* Tell driver that at least _CST is supported. */	pr->flags.has_cst = 1; 	for (i = 1; i <= count; i++) {		union acpi_object *element;		union acpi_object *obj;		struct acpi_power_register *reg;		struct acpi_processor_cx cx; 		memset(&cx, 0, sizeof(cx)); 		element = &(cst->package.elements[i]);		if (element->type != ACPI_TYPE_PACKAGE)			continue; 		if (element->package.count != 4)			continue; 		obj = &(element->package.elements[0]); 		if (obj->type != ACPI_TYPE_BUFFER)			continue; 		reg = (struct acpi_power_register *)obj->buffer.pointer; 		if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&		    (reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE))			continue; 		/* There should be an easy way to extract an integer... */		obj = &(element->package.elements[1]);		if (obj->type != ACPI_TYPE_INTEGER)			continue; 		cx.type = obj->integer.value;		/*		 * Some buggy BIOSes won't list C1 in _CST -		 * Let acpi_processor_get_power_info_default() handle them later		 */		if (i == 1 && cx.type != ACPI_STATE_C1)			current_count++; 		cx.address = reg->address;		cx.index = current_count + 1; 		cx.entry_method = ACPI_CSTATE_SYSTEMIO;		if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {			if (acpi_processor_ffh_cstate_probe					(pr->id, &cx, reg) == 0) {				cx.entry_method = ACPI_CSTATE_FFH;			} else if (cx.type == ACPI_STATE_C1) {				/*				 * C1 is a special case where FIXED_HARDWARE				 * can be handled in non-MWAIT way as well.				 * In that case, save this _CST entry info.				 * Otherwise, ignore this info and continue.				 */				cx.entry_method = ACPI_CSTATE_HALT;				snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");			} else {				continue;			}			if (cx.type == ACPI_STATE_C1 &&			    (boot_option_idle_override == IDLE_NOMWAIT)) {				/*				 * In most cases the C1 space_id obtained from				 * _CST object is FIXED_HARDWARE access mode.				 * But when the option of idle=halt is added,				 * the entry_method type should be changed from				 * CSTATE_FFH to CSTATE_HALT.				 * When the option of idle=nomwait is added,				 * the C1 entry_method type should be				 * CSTATE_HALT.				 */				cx.entry_method = ACPI_CSTATE_HALT;				snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI HLT");			}		} else {			snprintf(cx.desc, ACPI_CX_DESC_LEN, "ACPI IOPORT 0x%x",				 cx.address);		} 		if (cx.type == ACPI_STATE_C1) {			cx.valid = 1;		} 		obj = &(element->package.elements[2]);		if (obj->type != ACPI_TYPE_INTEGER)			continue; 		cx.latency = obj->integer.value; 		obj = &(element->package.elements[3]);		if (obj->type != ACPI_TYPE_INTEGER)			continue; 		current_count++;		memcpy(&(pr->power.states[current_count]), &cx, sizeof(cx)); 		/*		 * We support total ACPI_PROCESSOR_MAX_POWER - 1		 * (From 1 through ACPI_PROCESSOR_MAX_POWER - 1)		 */		if (current_count >= (ACPI_PROCESSOR_MAX_POWER - 1)) {			pr_warn("Limiting number of power states to max (%d)\n",				ACPI_PROCESSOR_MAX_POWER);			pr_warn("Please increase ACPI_PROCESSOR_MAX_POWER if needed.\n");			break;		}	} 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d power states\n",			  current_count)); 	/* Validate number of power states discovered */	if (current_count < 2)		ret = -EFAULT;       end:	kfree(buffer.pointer); 	return ret;} static void acpi_processor_power_verify_c3(struct acpi_processor *pr,					   struct acpi_processor_cx *cx){	static int bm_check_flag = -1;	static int bm_control_flag = -1;  	if (!cx->address)		return; 	/*	 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)	 * DMA transfers are used by any ISA device to avoid livelock.	 * Note that we could disable Type-F DMA (as recommended by	 * the erratum), but this is known to disrupt certain ISA	 * devices thus we take the conservative approach.	 */	else if (errata.piix4.fdma) {		ACPI_DEBUG_PRINT((ACPI_DB_INFO,				  "C3 not supported on PIIX4 with Type-F DMA\n"));		return;	} 	/* All the logic here assumes flags.bm_check is same across all CPUs */	if (bm_check_flag == -1) {		/* Determine whether bm_check is needed based on CPU  */		acpi_processor_power_init_bm_check(&(pr->flags), pr->id);		bm_check_flag = pr->flags.bm_check;		bm_control_flag = pr->flags.bm_control;	} else {		pr->flags.bm_check = bm_check_flag;		pr->flags.bm_control = bm_control_flag;	} 	if (pr->flags.bm_check) {		if (!pr->flags.bm_control) {			if (pr->flags.has_cst != 1) {				/* bus mastering control is necessary */				ACPI_DEBUG_PRINT((ACPI_DB_INFO,					"C3 support requires BM control\n"));				return;

Lines 1–500 of 1484.