diff options
Diffstat (limited to 'drivers/acpi/processor_driver.c')
| -rw-r--r-- | drivers/acpi/processor_driver.c | 75 | 
1 files changed, 53 insertions, 22 deletions
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index e78c2a52ea4..e83311bf1eb 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -44,6 +44,7 @@  #include <linux/moduleparam.h>  #include <linux/cpuidle.h>  #include <linux/slab.h> +#include <linux/acpi.h>  #include <asm/io.h>  #include <asm/cpu.h> @@ -282,7 +283,9 @@ static int acpi_processor_get_info(struct acpi_device *device)  		/* 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"); +			dev_err(&device->dev, +				"Failed to evaluate processor object (0x%x)\n", +				status);  			return -ENODEV;  		} @@ -301,8 +304,9 @@ static int acpi_processor_get_info(struct acpi_device *device)  		status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,  						NULL, &value);  		if (ACPI_FAILURE(status)) { -			printk(KERN_ERR PREFIX -			    "Evaluating processor _UID [%#x]\n", status); +			dev_err(&device->dev, +				"Failed to evaluate processor _UID (0x%x)\n", +				status);  			return -ENODEV;  		}  		device_declaration = 1; @@ -345,7 +349,7 @@ static int acpi_processor_get_info(struct acpi_device *device)  	if (!object.processor.pblk_address)  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));  	else if (object.processor.pblk_length != 6) -		printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", +		dev_err(&device->dev, "Invalid PBLK length [%d]\n",  			    object.processor.pblk_length);  	else {  		pr->throttling.address = object.processor.pblk_address; @@ -409,6 +413,7 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event)  		acpi_bus_generate_proc_event(device, event, 0);  		acpi_bus_generate_netlink_event(device->pnp.device_class,  						  dev_name(&device->dev), event, 0); +		break;  	default:  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,  				  "Unsupported event [0x%x]\n", event)); @@ -429,8 +434,8 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,  		 * Initialize missing things  		 */  		if (pr->flags.need_hotplug_init) { -			printk(KERN_INFO "Will online and init hotplugged " -			       "CPU: %d\n", pr->id); +			pr_info("Will online and init hotplugged CPU: %d\n", +				pr->id);  			WARN(acpi_processor_start(pr), "Failed to start CPU:"  				" %d\n", pr->id);  			pr->flags.need_hotplug_init = 0; @@ -491,14 +496,16 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)  				   &pr->cdev->device.kobj,  				   "thermal_cooling");  	if (result) { -		printk(KERN_ERR PREFIX "Create sysfs link\n"); +		dev_err(&device->dev, +			"Failed to create sysfs link 'thermal_cooling'\n");  		goto err_thermal_unregister;  	}  	result = sysfs_create_link(&pr->cdev->device.kobj,  				   &device->dev.kobj,  				   "device");  	if (result) { -		printk(KERN_ERR PREFIX "Create sysfs link\n"); +		dev_err(&pr->cdev->device, +			"Failed to create sysfs link 'device'\n");  		goto err_remove_sysfs_thermal;  	} @@ -560,8 +567,9 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)  	 */  	if (per_cpu(processor_device_array, pr->id) != NULL &&  	    per_cpu(processor_device_array, pr->id) != device) { -		printk(KERN_WARNING "BIOS reported wrong ACPI id " -			"for the processor\n"); +		dev_warn(&device->dev, +			"BIOS reported wrong ACPI id %d for the processor\n", +			pr->id);  		result = -ENODEV;  		goto err_free_cpumask;  	} @@ -694,8 +702,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)  static void acpi_processor_hotplug_notify(acpi_handle handle,  					  u32 event, void *data)  { -	struct acpi_processor *pr;  	struct acpi_device *device = NULL; +	struct acpi_eject_event *ej_event = NULL;  	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */  	int result; @@ -715,7 +723,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,  		result = acpi_processor_device_add(handle, &device);  		if (result) { -			printk(KERN_ERR PREFIX "Unable to add the device\n"); +			acpi_handle_err(handle, "Unable to add the device\n");  			break;  		} @@ -727,20 +735,29 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,  				  "received ACPI_NOTIFY_EJECT_REQUEST\n"));  		if (acpi_bus_get_device(handle, &device)) { -			printk(KERN_ERR PREFIX -				    "Device don't exist, dropping EJECT\n"); +			acpi_handle_err(handle, +				"Device don't exist, dropping EJECT\n");  			break;  		} -		pr = acpi_driver_data(device); -		if (!pr) { -			printk(KERN_ERR PREFIX -				    "Driver data is NULL, dropping EJECT\n"); +		if (!acpi_driver_data(device)) { +			acpi_handle_err(handle, +				"Driver data is NULL, dropping EJECT\n");  			break;  		} -		/* REVISIT: update when eject is supported */ -		ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; -		break; +		ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); +		if (!ej_event) { +			acpi_handle_err(handle, "No memory, dropping EJECT\n"); +			break; +		} + +		ej_event->handle = handle; +		ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; +		acpi_os_hotplug_execute(acpi_bus_hot_remove_device, +					(void *)ej_event); + +		/* eject is performed asynchronously */ +		return;  	default:  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -840,7 +857,7 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)  	 * and do it when the CPU gets online the first time  	 * TBD: Cleanup above functions and try to do this more elegant.  	 */ -	printk(KERN_INFO "CPU %d got hotplugged\n", pr->id); +	pr_info("CPU %d got hotplugged\n", pr->id);  	pr->flags.need_hotplug_init = 1;  	return AE_OK; @@ -851,8 +868,22 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr)  	if (cpu_online(pr->id))  		cpu_down(pr->id); +	get_online_cpus(); +	/* +	 * The cpu might become online again at this point. So we check whether +	 * the cpu has been onlined or not. If the cpu became online, it means +	 * that someone wants to use the cpu. So acpi_processor_handle_eject() +	 * returns -EAGAIN. +	 */ +	if (unlikely(cpu_online(pr->id))) { +		put_online_cpus(); +		pr_warn("Failed to remove CPU %d, because other task " +			"brought the CPU back online\n", pr->id); +		return -EAGAIN; +	}  	arch_unregister_cpu(pr->id);  	acpi_unmap_lsapic(pr->id); +	put_online_cpus();  	return (0);  }  #else  |