Merge branch 'd3' into release
Conflicts: drivers/acpi/sleep.c This was a text conflict betweena2ef5c4fd4(ACPI: Move module parameter gts and bfs to sleep.c) which added #include <linux/module.h> andb24e509885(ACPI, PCI: Move acpi_dev_run_wake() to ACPI core) which added #include <linux/pm_runtime.h> The resolution was to take them both. Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
		
						commit
						ec612fcf43
					
				| @ -40,9 +40,11 @@ | ||||
| #include <linux/init.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/pm_runtime.h> | ||||
| #include <acpi/acpi_bus.h> | ||||
| #include <acpi/acpi_drivers.h> | ||||
| #include "sleep.h" | ||||
| #include "internal.h" | ||||
| 
 | ||||
| #define PREFIX "ACPI: " | ||||
| 
 | ||||
| @ -77,6 +79,20 @@ static struct acpi_driver acpi_power_driver = { | ||||
| 		}, | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * A power managed device | ||||
|  * A device may rely on multiple power resources. | ||||
|  * */ | ||||
| struct acpi_power_managed_device { | ||||
| 	struct device *dev; /* The physical device */ | ||||
| 	acpi_handle *handle; | ||||
| }; | ||||
| 
 | ||||
| struct acpi_power_resource_device { | ||||
| 	struct acpi_power_managed_device *device; | ||||
| 	struct acpi_power_resource_device *next; | ||||
| }; | ||||
| 
 | ||||
| struct acpi_power_resource { | ||||
| 	struct acpi_device * device; | ||||
| 	acpi_bus_id name; | ||||
| @ -84,6 +100,9 @@ struct acpi_power_resource { | ||||
| 	u32 order; | ||||
| 	unsigned int ref_count; | ||||
| 	struct mutex resource_lock; | ||||
| 
 | ||||
| 	/* List of devices relying on this power resource */ | ||||
| 	struct acpi_power_resource_device *devices; | ||||
| }; | ||||
| 
 | ||||
| static struct list_head acpi_power_resource_list; | ||||
| @ -183,8 +202,26 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Resume the device when all power resources in _PR0 are on */ | ||||
| static void acpi_power_on_device(struct acpi_power_managed_device *device) | ||||
| { | ||||
| 	struct acpi_device *acpi_dev; | ||||
| 	acpi_handle handle = device->handle; | ||||
| 	int state; | ||||
| 
 | ||||
| 	if (acpi_bus_get_device(handle, &acpi_dev)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(acpi_power_get_inferred_state(acpi_dev, &state)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (state == ACPI_STATE_D0 && pm_runtime_suspended(device->dev)) | ||||
| 		pm_request_resume(device->dev); | ||||
| } | ||||
| 
 | ||||
| static int __acpi_power_on(struct acpi_power_resource *resource) | ||||
| { | ||||
| 	struct acpi_power_resource_device *device_list = resource->devices; | ||||
| 	acpi_status status = AE_OK; | ||||
| 
 | ||||
| 	status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); | ||||
| @ -197,6 +234,12 @@ static int __acpi_power_on(struct acpi_power_resource *resource) | ||||
| 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", | ||||
| 			  resource->name)); | ||||
| 
 | ||||
| 	while (device_list) { | ||||
| 		acpi_power_on_device(device_list->device); | ||||
| 
 | ||||
| 		device_list = device_list->next; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -299,6 +342,125 @@ static int acpi_power_on_list(struct acpi_handle_list *list) | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| static void __acpi_power_resource_unregister_device(struct device *dev, | ||||
| 		acpi_handle res_handle) | ||||
| { | ||||
| 	struct acpi_power_resource *resource = NULL; | ||||
| 	struct acpi_power_resource_device *prev, *curr; | ||||
| 
 | ||||
| 	if (acpi_power_get_context(res_handle, &resource)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&resource->resource_lock); | ||||
| 	prev = NULL; | ||||
| 	curr = resource->devices; | ||||
| 	while (curr) { | ||||
| 		if (curr->device->dev == dev) { | ||||
| 			if (!prev) | ||||
| 				resource->devices = curr->next; | ||||
| 			else | ||||
| 				prev->next = curr->next; | ||||
| 
 | ||||
| 			kfree(curr); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		prev = curr; | ||||
| 		curr = curr->next; | ||||
| 	} | ||||
| 	mutex_unlock(&resource->resource_lock); | ||||
| } | ||||
| 
 | ||||
| /* Unlink dev from all power resources in _PR0 */ | ||||
| void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle) | ||||
| { | ||||
| 	struct acpi_device *acpi_dev; | ||||
| 	struct acpi_handle_list *list; | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (!dev || !handle) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (acpi_bus_get_device(handle, &acpi_dev)) | ||||
| 		return; | ||||
| 
 | ||||
| 	list = &acpi_dev->power.states[ACPI_STATE_D0].resources; | ||||
| 
 | ||||
| 	for (i = 0; i < list->count; i++) | ||||
| 		__acpi_power_resource_unregister_device(dev, | ||||
| 			list->handles[i]); | ||||
| } | ||||
| 
 | ||||
| static int __acpi_power_resource_register_device( | ||||
| 	struct acpi_power_managed_device *powered_device, acpi_handle handle) | ||||
| { | ||||
| 	struct acpi_power_resource *resource = NULL; | ||||
| 	struct acpi_power_resource_device *power_resource_device; | ||||
| 	int result; | ||||
| 
 | ||||
| 	result = acpi_power_get_context(handle, &resource); | ||||
| 	if (result) | ||||
| 		return result; | ||||
| 
 | ||||
| 	power_resource_device = kzalloc( | ||||
| 		sizeof(*power_resource_device), GFP_KERNEL); | ||||
| 	if (!power_resource_device) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	power_resource_device->device = powered_device; | ||||
| 
 | ||||
| 	mutex_lock(&resource->resource_lock); | ||||
| 	power_resource_device->next = resource->devices; | ||||
| 	resource->devices = power_resource_device; | ||||
| 	mutex_unlock(&resource->resource_lock); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Link dev to all power resources in _PR0 */ | ||||
| int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | ||||
| { | ||||
| 	struct acpi_device *acpi_dev; | ||||
| 	struct acpi_handle_list *list; | ||||
| 	struct acpi_power_managed_device *powered_device; | ||||
| 	int i, ret; | ||||
| 
 | ||||
| 	if (!dev || !handle) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	ret = acpi_bus_get_device(handle, &acpi_dev); | ||||
| 	if (ret) | ||||
| 		goto no_power_resource; | ||||
| 
 | ||||
| 	if (!acpi_dev->power.flags.power_resources) | ||||
| 		goto no_power_resource; | ||||
| 
 | ||||
| 	powered_device = kzalloc(sizeof(*powered_device), GFP_KERNEL); | ||||
| 	if (!powered_device) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	powered_device->dev = dev; | ||||
| 	powered_device->handle = handle; | ||||
| 
 | ||||
| 	list = &acpi_dev->power.states[ACPI_STATE_D0].resources; | ||||
| 
 | ||||
| 	for (i = 0; i < list->count; i++) { | ||||
| 		ret = __acpi_power_resource_register_device(powered_device, | ||||
| 			list->handles[i]); | ||||
| 
 | ||||
| 		if (ret) { | ||||
| 			acpi_power_resource_unregister_device(dev, handle); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| 
 | ||||
| no_power_resource: | ||||
| 	printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); | ||||
| 	return -ENODEV; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in | ||||
|  *                          ACPI 3.0) _PSW (Power State Wake) | ||||
| @ -500,14 +662,14 @@ int acpi_power_transition(struct acpi_device *device, int state) | ||||
| { | ||||
| 	int result; | ||||
| 
 | ||||
| 	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | ||||
| 	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	if (device->power.state == state) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if ((device->power.state < ACPI_STATE_D0) | ||||
| 	    || (device->power.state > ACPI_STATE_D3)) | ||||
| 	    || (device->power.state > ACPI_STATE_D3_COLD)) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	/* TBD: Resources must be ordered. */ | ||||
|  | ||||
| @ -884,6 +884,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | ||||
| 				acpi_bus_add_power_resource(ps->resources.handles[j]); | ||||
| 		} | ||||
| 
 | ||||
| 		/* The exist of _PR3 indicates D3Cold support */ | ||||
| 		if (i == ACPI_STATE_D3) { | ||||
| 			status = acpi_get_handle(device->handle, object_name, &handle); | ||||
| 			if (ACPI_SUCCESS(status)) | ||||
| 				device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Evaluate "_PSx" to see if we can do explicit sets */ | ||||
| 		object_name[2] = 'S'; | ||||
| 		status = acpi_get_handle(device->handle, object_name, &handle); | ||||
|  | ||||
| @ -18,6 +18,7 @@ | ||||
| #include <linux/reboot.h> | ||||
| #include <linux/acpi.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/pm_runtime.h> | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| @ -752,6 +753,40 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p) | ||||
| #endif /* CONFIG_PM */ | ||||
| 
 | ||||
| #ifdef CONFIG_PM_SLEEP | ||||
| /**
 | ||||
|  * acpi_pm_device_run_wake - Enable/disable wake-up for given device. | ||||
|  * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||||
|  * @enable: Whether enable or disable the wake-up functionality. | ||||
|  * | ||||
|  * Find the ACPI device object corresponding to @pci_dev and try to | ||||
|  * enable/disable the GPE associated with it. | ||||
|  */ | ||||
| int acpi_pm_device_run_wake(struct device *phys_dev, bool enable) | ||||
| { | ||||
| 	struct acpi_device *dev; | ||||
| 	acpi_handle handle; | ||||
| 
 | ||||
| 	if (!device_run_wake(phys_dev)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	handle = DEVICE_ACPI_HANDLE(phys_dev); | ||||
| 	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||||
| 		dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||||
| 			__func__); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	if (enable) { | ||||
| 		acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||||
| 		acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||||
| 	} else { | ||||
| 		acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||||
| 		acpi_disable_wakeup_device_power(dev); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *	acpi_pm_device_sleep_wake - enable or disable the system wake-up | ||||
|  *                                  capability of given device | ||||
|  | ||||
| @ -277,40 +277,6 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * acpi_dev_run_wake - Enable/disable wake-up for given device. | ||||
|  * @phys_dev: Device to enable/disable the platform to wake-up the system for. | ||||
|  * @enable: Whether enable or disable the wake-up functionality. | ||||
|  * | ||||
|  * Find the ACPI device object corresponding to @pci_dev and try to | ||||
|  * enable/disable the GPE associated with it. | ||||
|  */ | ||||
| static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | ||||
| { | ||||
| 	struct acpi_device *dev; | ||||
| 	acpi_handle handle; | ||||
| 
 | ||||
| 	if (!device_run_wake(phys_dev)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	handle = DEVICE_ACPI_HANDLE(phys_dev); | ||||
| 	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &dev))) { | ||||
| 		dev_dbg(phys_dev, "ACPI handle has no context in %s!\n", | ||||
| 			__func__); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	if (enable) { | ||||
| 		acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | ||||
| 		acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||||
| 	} else { | ||||
| 		acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); | ||||
| 		acpi_disable_wakeup_device_power(dev); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||||
| { | ||||
| 	while (bus->parent) { | ||||
| @ -318,14 +284,14 @@ static void acpi_pci_propagate_run_wake(struct pci_bus *bus, bool enable) | ||||
| 
 | ||||
| 		if (bridge->pme_interrupt) | ||||
| 			return; | ||||
| 		if (!acpi_dev_run_wake(&bridge->dev, enable)) | ||||
| 		if (!acpi_pm_device_run_wake(&bridge->dev, enable)) | ||||
| 			return; | ||||
| 		bus = bus->parent; | ||||
| 	} | ||||
| 
 | ||||
| 	/* We have reached the root bus. */ | ||||
| 	if (bus->bridge) | ||||
| 		acpi_dev_run_wake(bus->bridge, enable); | ||||
| 		acpi_pm_device_run_wake(bus->bridge, enable); | ||||
| } | ||||
| 
 | ||||
| static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | ||||
| @ -333,7 +299,7 @@ static int acpi_pci_run_wake(struct pci_dev *dev, bool enable) | ||||
| 	if (dev->pme_interrupt) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (!acpi_dev_run_wake(&dev->dev, enable)) | ||||
| 	if (!acpi_pm_device_run_wake(&dev->dev, enable)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	acpi_pci_propagate_run_wake(dev->bus, enable); | ||||
|  | ||||
| @ -323,6 +323,8 @@ int acpi_bus_set_power(acpi_handle handle, int state); | ||||
| int acpi_bus_update_power(acpi_handle handle, int *state_p); | ||||
| bool acpi_bus_power_manageable(acpi_handle handle); | ||||
| bool acpi_bus_can_wakeup(acpi_handle handle); | ||||
| int acpi_power_resource_register_device(struct device *dev, acpi_handle handle); | ||||
| void acpi_power_resource_unregister_device(struct device *dev, acpi_handle handle); | ||||
| #ifdef CONFIG_ACPI_PROC_EVENT | ||||
| int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); | ||||
| int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); | ||||
| @ -392,8 +394,13 @@ static inline int acpi_pm_device_sleep_state(struct device *d, int *p) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PM_SLEEP | ||||
| int acpi_pm_device_run_wake(struct device *, bool); | ||||
| int acpi_pm_device_sleep_wake(struct device *, bool); | ||||
| #else | ||||
| static inline int acpi_pm_device_run_wake(struct device *dev, bool enable) | ||||
| { | ||||
| 	return -ENODEV; | ||||
| } | ||||
| static inline int acpi_pm_device_sleep_wake(struct device *dev, bool enable) | ||||
| { | ||||
| 	return -ENODEV; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user