Pull bugzilla-5000 into release branch
This commit is contained in:
commit
8f2ddb37e5
|
@ -205,12 +205,14 @@ int acpi_bus_set_power(acpi_handle handle, int state)
|
||||||
* Get device's current power state if it's unknown
|
* Get device's current power state if it's unknown
|
||||||
* This means device power state isn't initialized or previous setting failed
|
* This means device power state isn't initialized or previous setting failed
|
||||||
*/
|
*/
|
||||||
if (device->power.state == ACPI_STATE_UNKNOWN)
|
if (!device->flags.force_power_state) {
|
||||||
acpi_bus_get_power(device->handle, &device->power.state);
|
if (device->power.state == ACPI_STATE_UNKNOWN)
|
||||||
if (state == device->power.state) {
|
acpi_bus_get_power(device->handle, &device->power.state);
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
|
if (state == device->power.state) {
|
||||||
state));
|
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
|
||||||
return_VALUE(0);
|
state));
|
||||||
|
return_VALUE(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!device->power.states[state].flags.valid) {
|
if (!device->power.states[state].flags.valid) {
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n",
|
ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Device does not support D%d\n",
|
||||||
|
|
|
@ -48,6 +48,8 @@ MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
static int acpi_fan_add(struct acpi_device *device);
|
static int acpi_fan_add(struct acpi_device *device);
|
||||||
static int acpi_fan_remove(struct acpi_device *device, int type);
|
static int acpi_fan_remove(struct acpi_device *device, int type);
|
||||||
|
static int acpi_fan_suspend(struct acpi_device *device, int state);
|
||||||
|
static int acpi_fan_resume(struct acpi_device *device, int state);
|
||||||
|
|
||||||
static struct acpi_driver acpi_fan_driver = {
|
static struct acpi_driver acpi_fan_driver = {
|
||||||
.name = ACPI_FAN_DRIVER_NAME,
|
.name = ACPI_FAN_DRIVER_NAME,
|
||||||
|
@ -56,6 +58,8 @@ static struct acpi_driver acpi_fan_driver = {
|
||||||
.ops = {
|
.ops = {
|
||||||
.add = acpi_fan_add,
|
.add = acpi_fan_add,
|
||||||
.remove = acpi_fan_remove,
|
.remove = acpi_fan_remove,
|
||||||
|
.suspend = acpi_fan_suspend,
|
||||||
|
.resume = acpi_fan_resume,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -206,6 +210,10 @@ static int acpi_fan_add(struct acpi_device *device)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device->flags.force_power_state = 1;
|
||||||
|
acpi_bus_set_power(device->handle, state);
|
||||||
|
device->flags.force_power_state = 0;
|
||||||
|
|
||||||
result = acpi_fan_add_fs(device);
|
result = acpi_fan_add_fs(device);
|
||||||
if (result)
|
if (result)
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -239,6 +247,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
|
||||||
return_VALUE(0);
|
return_VALUE(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int acpi_fan_suspend(struct acpi_device *device, int state)
|
||||||
|
{
|
||||||
|
if (!device)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
acpi_bus_set_power(device->handle, ACPI_STATE_D0);
|
||||||
|
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int acpi_fan_resume(struct acpi_device *device, int state)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int power_state = 0;
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
result = acpi_bus_get_power(device->handle, &power_state);
|
||||||
|
if (result) {
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
|
||||||
|
"Error reading fan power state\n"));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->flags.force_power_state = 1;
|
||||||
|
acpi_bus_set_power(device->handle, power_state);
|
||||||
|
device->flags.force_power_state = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init acpi_fan_init(void)
|
static int __init acpi_fan_init(void)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
|
@ -1341,6 +1341,100 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
|
||||||
return_VALUE(result);
|
return_VALUE(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline struct acpi_device * to_acpi_dev(struct device * dev)
|
||||||
|
{
|
||||||
|
return container_of(dev, struct acpi_device, dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct acpi_device * dev, * next;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
spin_lock(&acpi_device_lock);
|
||||||
|
list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
|
||||||
|
if (dev->driver && dev->driver->ops.suspend) {
|
||||||
|
spin_unlock(&acpi_device_lock);
|
||||||
|
result = dev->driver->ops.suspend(dev, 0);
|
||||||
|
if (result) {
|
||||||
|
printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
|
||||||
|
acpi_device_name(dev),
|
||||||
|
acpi_device_bid(dev), result);
|
||||||
|
}
|
||||||
|
spin_lock(&acpi_device_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&acpi_device_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int acpi_device_suspend(struct device * dev, pm_message_t state)
|
||||||
|
{
|
||||||
|
struct acpi_device * acpi_dev = to_acpi_dev(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, we should only register 1 generic device -
|
||||||
|
* the ACPI root device - and from there, we walk the
|
||||||
|
* tree of ACPI devices to suspend each one using the
|
||||||
|
* ACPI driver methods.
|
||||||
|
*/
|
||||||
|
if (acpi_dev->handle == ACPI_ROOT_OBJECT)
|
||||||
|
root_suspend(acpi_dev, state);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int root_resume(struct acpi_device * acpi_dev)
|
||||||
|
{
|
||||||
|
struct acpi_device * dev, * next;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
spin_lock(&acpi_device_lock);
|
||||||
|
list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
|
||||||
|
if (dev->driver && dev->driver->ops.resume) {
|
||||||
|
spin_unlock(&acpi_device_lock);
|
||||||
|
result = dev->driver->ops.resume(dev, 0);
|
||||||
|
if (result) {
|
||||||
|
printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
|
||||||
|
acpi_device_name(dev),
|
||||||
|
acpi_device_bid(dev), result);
|
||||||
|
}
|
||||||
|
spin_lock(&acpi_device_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&acpi_device_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int acpi_device_resume(struct device * dev)
|
||||||
|
{
|
||||||
|
struct acpi_device * acpi_dev = to_acpi_dev(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, we should only register 1 generic device -
|
||||||
|
* the ACPI root device - and from there, we walk the
|
||||||
|
* tree of ACPI devices to resume each one using the
|
||||||
|
* ACPI driver methods.
|
||||||
|
*/
|
||||||
|
if (acpi_dev->handle == ACPI_ROOT_OBJECT)
|
||||||
|
root_resume(acpi_dev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct bus_type acpi_bus_type = {
|
||||||
|
.name = "acpi",
|
||||||
|
.suspend = acpi_device_suspend,
|
||||||
|
.resume = acpi_device_resume,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int __init acpi_scan_init(void)
|
static int __init acpi_scan_init(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -1353,6 +1447,12 @@ static int __init acpi_scan_init(void)
|
||||||
|
|
||||||
kset_register(&acpi_namespace_kset);
|
kset_register(&acpi_namespace_kset);
|
||||||
|
|
||||||
|
result = bus_register(&acpi_bus_type);
|
||||||
|
if (result) {
|
||||||
|
/* We don't want to quit even if we failed to add suspend/resume */
|
||||||
|
printk(KERN_ERR PREFIX "Could not register bus type\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the root device in the bus's device tree
|
* Create the root device in the bus's device tree
|
||||||
*/
|
*/
|
||||||
|
@ -1362,6 +1462,16 @@ static int __init acpi_scan_init(void)
|
||||||
goto Done;
|
goto Done;
|
||||||
|
|
||||||
result = acpi_start_single_object(acpi_root);
|
result = acpi_start_single_object(acpi_root);
|
||||||
|
if (result)
|
||||||
|
goto Done;
|
||||||
|
|
||||||
|
acpi_root->dev.bus = &acpi_bus_type;
|
||||||
|
snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
|
||||||
|
result = device_register(&acpi_root->dev);
|
||||||
|
if (result) {
|
||||||
|
/* We don't want to quit even if we failed to add suspend/resume */
|
||||||
|
printk(KERN_ERR PREFIX "Could not register device\n");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enumerate devices in the ACPI namespace.
|
* Enumerate devices in the ACPI namespace.
|
||||||
|
|
|
@ -82,6 +82,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
|
||||||
|
|
||||||
static int acpi_thermal_add(struct acpi_device *device);
|
static int acpi_thermal_add(struct acpi_device *device);
|
||||||
static int acpi_thermal_remove(struct acpi_device *device, int type);
|
static int acpi_thermal_remove(struct acpi_device *device, int type);
|
||||||
|
static int acpi_thermal_resume(struct acpi_device *device, int state);
|
||||||
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
|
static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
|
||||||
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
|
static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
|
||||||
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
|
static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
|
||||||
|
@ -103,6 +104,7 @@ static struct acpi_driver acpi_thermal_driver = {
|
||||||
.ops = {
|
.ops = {
|
||||||
.add = acpi_thermal_add,
|
.add = acpi_thermal_add,
|
||||||
.remove = acpi_thermal_remove,
|
.remove = acpi_thermal_remove,
|
||||||
|
.resume = acpi_thermal_resume,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1417,6 +1419,20 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
|
||||||
return_VALUE(0);
|
return_VALUE(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int acpi_thermal_resume(struct acpi_device *device, int state)
|
||||||
|
{
|
||||||
|
struct acpi_thermal *tz = NULL;
|
||||||
|
|
||||||
|
if (!device || !acpi_driver_data(device))
|
||||||
|
return_VALUE(-EINVAL);
|
||||||
|
|
||||||
|
tz = (struct acpi_thermal *)acpi_driver_data(device);
|
||||||
|
|
||||||
|
acpi_thermal_check(tz);
|
||||||
|
|
||||||
|
return AE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int __init acpi_thermal_init(void)
|
static int __init acpi_thermal_init(void)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#ifndef __ACPI_BUS_H__
|
#ifndef __ACPI_BUS_H__
|
||||||
#define __ACPI_BUS_H__
|
#define __ACPI_BUS_H__
|
||||||
|
|
||||||
#include <linux/kobject.h>
|
#include <linux/device.h>
|
||||||
|
|
||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
|
|
||||||
|
@ -169,7 +169,8 @@ struct acpi_device_flags {
|
||||||
u32 power_manageable:1;
|
u32 power_manageable:1;
|
||||||
u32 performance_manageable:1;
|
u32 performance_manageable:1;
|
||||||
u32 wake_capable:1; /* Wakeup(_PRW) supported? */
|
u32 wake_capable:1; /* Wakeup(_PRW) supported? */
|
||||||
u32 reserved:20;
|
u32 force_power_state:1;
|
||||||
|
u32 reserved:19;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* File System */
|
/* File System */
|
||||||
|
@ -296,6 +297,7 @@ struct acpi_device {
|
||||||
struct acpi_driver *driver;
|
struct acpi_driver *driver;
|
||||||
void *driver_data;
|
void *driver_data;
|
||||||
struct kobject kobj;
|
struct kobject kobj;
|
||||||
|
struct device dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define acpi_driver_data(d) ((d)->driver_data)
|
#define acpi_driver_data(d) ((d)->driver_data)
|
||||||
|
|
Loading…
Reference in New Issue