ACPI: create acpi_device_suspend()/acpi_device_resume()

updated and tested by Konstantin Karasyov

http://bugzilla.kernel.org/show_bug.cgi?id=5000

Signed-off-by: Patrick Mochel <patrick.mochel@intel.com>
Signed-off-by: Konstantin Karasyov <konstantin.karasyov @intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Patrick Mochel 2006-05-10 10:33:00 -04:00 committed by Len Brown
parent d8c3291c73
commit 5b3272655a
2 changed files with 120 additions and 1 deletions

View file

@ -1371,6 +1371,108 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
return_VALUE(result);
}
static 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)
{
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);
/* TBD: What suspend state should be passed
* to device?
*/
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);
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);
/* TBD: What suspend state should be passed
* to device?
*/
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)
{
int result;
@ -1383,6 +1485,12 @@ static int __init acpi_scan_init(void)
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
*/
@ -1392,6 +1500,16 @@ static int __init acpi_scan_init(void)
goto Done;
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.

View file

@ -26,7 +26,7 @@
#ifndef __ACPI_BUS_H__
#define __ACPI_BUS_H__
#include <linux/kobject.h>
#include <linux/device.h>
#include <acpi/acpi.h>
@ -296,6 +296,7 @@ struct acpi_device {
struct acpi_driver *driver;
void *driver_data;
struct kobject kobj;
struct device dev;
};
#define acpi_driver_data(d) ((d)->driver_data)