diff options
Diffstat (limited to 'drivers/acpi/processor_core.c')
| -rw-r--r-- | drivers/acpi/processor_core.c | 93 | 
1 files changed, 52 insertions, 41 deletions
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 24a362f8034..34948362f41 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -59,7 +59,6 @@  #include <acpi/acpi_drivers.h>  #include <acpi/processor.h> -#define ACPI_PROCESSOR_COMPONENT	0x01000000  #define ACPI_PROCESSOR_CLASS		"processor"  #define ACPI_PROCESSOR_DEVICE_NAME	"Processor"  #define ACPI_PROCESSOR_FILE_INFO	"info" @@ -89,6 +88,7 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr);  static const struct acpi_device_id processor_device_ids[] = { +	{ACPI_PROCESSOR_OBJECT_HID, 0},  	{ACPI_PROCESSOR_HID, 0},  	{"", 0},  }; @@ -409,7 +409,7 @@ static int acpi_processor_remove_fs(struct acpi_device *device)  /* Use the acpiid in MADT to map cpus in case of SMP */  #ifndef CONFIG_SMP -static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;} +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }  #else  static struct acpi_table_madt *madt; @@ -428,27 +428,35 @@ static int map_lapic_id(struct acpi_subtable_header *entry,  }  static int map_lsapic_id(struct acpi_subtable_header *entry, -		  u32 acpi_id, int *apic_id) +		int device_declaration, u32 acpi_id, int *apic_id)  {  	struct acpi_madt_local_sapic *lsapic =  		(struct acpi_madt_local_sapic *)entry; +	u32 tmp = (lsapic->id << 8) | lsapic->eid; +  	/* Only check enabled APICs*/ -	if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { -		/* First check against id */ -		if (lsapic->processor_id == acpi_id) { -			*apic_id = (lsapic->id << 8) | lsapic->eid; -			return 1; -		/* Check against optional uid */ -		} else if (entry->length >= 16 && -			lsapic->uid == acpi_id) { -			*apic_id = lsapic->uid; -			return 1; -		} -	} +	if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED)) +		return 0; + +	/* Device statement declaration type */ +	if (device_declaration) { +		if (entry->length < 16) +			printk(KERN_ERR PREFIX +			    "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n", +			    tmp); +		else if (lsapic->uid == acpi_id) +			goto found; +	/* Processor statement declaration type */ +	} else if (lsapic->processor_id == acpi_id) +		goto found; +  	return 0; +found: +	*apic_id = tmp; +	return 1;  } -static int map_madt_entry(u32 acpi_id) +static int map_madt_entry(int type, u32 acpi_id)  {  	unsigned long madt_end, entry;  	int apic_id = -1; @@ -469,7 +477,7 @@ static int map_madt_entry(u32 acpi_id)  			if (map_lapic_id(header, acpi_id, &apic_id))  				break;  		} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { -			if (map_lsapic_id(header, acpi_id, &apic_id)) +			if (map_lsapic_id(header, type, acpi_id, &apic_id))  				break;  		}  		entry += header->length; @@ -477,7 +485,7 @@ static int map_madt_entry(u32 acpi_id)  	return apic_id;  } -static int map_mat_entry(acpi_handle handle, u32 acpi_id) +static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)  {  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };  	union acpi_object *obj; @@ -500,7 +508,7 @@ static int map_mat_entry(acpi_handle handle, u32 acpi_id)  	if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {  		map_lapic_id(header, acpi_id, &apic_id);  	} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { -		map_lsapic_id(header, acpi_id, &apic_id); +		map_lsapic_id(header, type, acpi_id, &apic_id);  	}  exit: @@ -509,14 +517,14 @@ exit:  	return apic_id;  } -static int get_cpu_id(acpi_handle handle, u32 acpi_id) +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)  {  	int i;  	int apic_id = -1; -	apic_id = map_mat_entry(handle, acpi_id); +	apic_id = map_mat_entry(handle, type, acpi_id);  	if (apic_id == -1) -		apic_id = map_madt_entry(acpi_id); +		apic_id = map_madt_entry(type, acpi_id);  	if (apic_id == -1)  		return apic_id; @@ -532,15 +540,16 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)                                   Driver Interface     -------------------------------------------------------------------------- */ -static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid) +static int acpi_processor_get_info(struct acpi_device *device)  {  	acpi_status status = 0;  	union acpi_object object = { 0 };  	struct acpi_buffer buffer = { sizeof(union acpi_object), &object }; -	int cpu_index; +	struct acpi_processor *pr; +	int cpu_index, device_declaration = 0;  	static int cpu0_initialized; - +	pr = acpi_driver_data(device);  	if (!pr)  		return -EINVAL; @@ -561,22 +570,23 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,  				  "No bus mastering arbitration control\n")); -	/* Check if it is a Device with HID and UID */ -	if (has_uid) { +	if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) { +		/* +		 * Declared with "Device" statement; match _UID. +		 * Note that we don't handle string _UIDs yet. +		 */  		unsigned long long value;  		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,  						NULL, &value);  		if (ACPI_FAILURE(status)) { -			printk(KERN_ERR PREFIX "Evaluating processor _UID\n"); +			printk(KERN_ERR PREFIX +			    "Evaluating processor _UID [%#x]\n", status);  			return -ENODEV;  		} +		device_declaration = 1;  		pr->acpi_id = value;  	} else { -		/* -		* Evalute the processor object.  Note that it is common on SMP to -		* have the first (boot) processor with a valid PBLK address while -		* all others have a NULL address. -		*/ +		/* Declared with "Processor" statement; match ProcessorID */  		status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);  		if (ACPI_FAILURE(status)) {  			printk(KERN_ERR PREFIX "Evaluating processor object\n"); @@ -584,12 +594,13 @@ static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)  		}  		/* -		* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. -		*      >>> 'acpi_get_processor_id(acpi_id, &id)' in arch/xxx/acpi.c -		*/ +		 * TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP. +		 *      >>> 'acpi_get_processor_id(acpi_id, &id)' in +		 *      arch/xxx/acpi.c +		 */  		pr->acpi_id = object.processor.proc_id;  	} -	cpu_index = get_cpu_id(pr->handle, pr->acpi_id); +	cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);  	/* Handle UP system running SMP kernel, with no LAPIC in MADT */  	if (!cpu0_initialized && (cpu_index == -1) && @@ -661,7 +672,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)  	pr = acpi_driver_data(device); -	result = acpi_processor_get_info(pr, device->flags.unique_id); +	result = acpi_processor_get_info(device);  	if (result) {  		/* Processor is physically not present */  		return 0; @@ -761,20 +772,20 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)  		acpi_bus_generate_proc_event(device, event,  					pr->performance_platform_limit);  		acpi_bus_generate_netlink_event(device->pnp.device_class, -						  device->dev.bus_id, event, +						  dev_name(&device->dev), event,  						  pr->performance_platform_limit);  		break;  	case ACPI_PROCESSOR_NOTIFY_POWER:  		acpi_processor_cst_has_changed(pr);  		acpi_bus_generate_proc_event(device, event, 0);  		acpi_bus_generate_netlink_event(device->pnp.device_class, -						  device->dev.bus_id, event, 0); +						  dev_name(&device->dev), event, 0);  		break;  	case ACPI_PROCESSOR_NOTIFY_THROTTLING:  		acpi_processor_tstate_has_changed(pr);  		acpi_bus_generate_proc_event(device, event, 0);  		acpi_bus_generate_netlink_event(device->pnp.device_class, -						  device->dev.bus_id, event, 0); +						  dev_name(&device->dev), event, 0);  	default:  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,  				  "Unsupported event [0x%x]\n", event));  |