diff options
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
| -rw-r--r-- | drivers/acpi/processor_perflib.c | 30 | 
1 files changed, 25 insertions, 5 deletions
| diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 0af48a8554cd..a093dc163a42 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -333,6 +333,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)  	struct acpi_buffer state = { 0, NULL };  	union acpi_object *pss = NULL;  	int i; +	int last_invalid = -1;  	status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer); @@ -394,14 +395,33 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)  		    ((u32)(px->core_frequency * 1000) !=  		     (px->core_frequency * 1000))) {  			printk(KERN_ERR FW_BUG PREFIX -			       "Invalid BIOS _PSS frequency: 0x%llx MHz\n", -			       px->core_frequency); -			result = -EFAULT; -			kfree(pr->performance->states); -			goto end; +			       "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n", +			       pr->id, px->core_frequency); +			if (last_invalid == -1) +				last_invalid = i; +		} else { +			if (last_invalid != -1) { +				/* +				 * Copy this valid entry over last_invalid entry +				 */ +				memcpy(&(pr->performance->states[last_invalid]), +				       px, sizeof(struct acpi_processor_px)); +				++last_invalid; +			}  		}  	} +	if (last_invalid == 0) { +		printk(KERN_ERR FW_BUG PREFIX +		       "No valid BIOS _PSS frequency found for processor %d\n", pr->id); +		result = -EFAULT; +		kfree(pr->performance->states); +		pr->performance->states = NULL; +	} + +	if (last_invalid > 0) +		pr->performance->state_count = last_invalid; +        end:  	kfree(buffer.pointer); | 
