aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Mochel <patrick.mochel@intel.com>2006-05-10 10:33:00 -0400
committerLen Brown <len.brown@intel.com>2006-05-15 02:44:47 -0400
commit5b3272655a8e8a9a6e2503bc5a88fc9d9c8292a4 (patch)
treea292396e87e1bdafdca199ab1c1843302ccf00f6
parentd8c3291c73b958243b33f8509d4507e76dafd055 (diff)
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>
-rw-r--r--drivers/acpi/scan.c118
-rw-r--r--include/acpi/acpi_bus.h3
2 files changed, 120 insertions, 1 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a0ab828b2cc5..19ae9ff10210 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1371,6 +1371,108 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1371 return_VALUE(result); 1371 return_VALUE(result);
1372} 1372}
1373 1373
1374
1375static struct acpi_device * to_acpi_dev(struct device * dev)
1376{
1377 return container_of(dev, struct acpi_device, dev);
1378}
1379
1380
1381static int root_suspend(struct acpi_device * acpi_dev)
1382{
1383 struct acpi_device * dev, * next;
1384 int result;
1385
1386 spin_lock(&acpi_device_lock);
1387 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
1388 if (dev->driver && dev->driver->ops.suspend) {
1389 spin_unlock(&acpi_device_lock);
1390
1391 /* TBD: What suspend state should be passed
1392 * to device?
1393 */
1394 result = dev->driver->ops.suspend(dev, 0);
1395 if (result) {
1396 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
1397 acpi_device_name(dev),
1398 acpi_device_bid(dev), result);
1399 }
1400 spin_lock(&acpi_device_lock);
1401 }
1402 }
1403 spin_unlock(&acpi_device_lock);
1404 return 0;
1405}
1406
1407
1408static int acpi_device_suspend(struct device * dev, pm_message_t state)
1409{
1410 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1411
1412 /*
1413 * For now, we should only register 1 generic device -
1414 * the ACPI root device - and from there, we walk the
1415 * tree of ACPI devices to suspend each one using the
1416 * ACPI driver methods.
1417 */
1418 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1419 root_suspend(acpi_dev);
1420 return 0;
1421}
1422
1423
1424
1425static int root_resume(struct acpi_device * acpi_dev)
1426{
1427 struct acpi_device * dev, * next;
1428 int result;
1429
1430 spin_lock(&acpi_device_lock);
1431 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
1432 if (dev->driver && dev->driver->ops.resume) {
1433 spin_unlock(&acpi_device_lock);
1434
1435 /* TBD: What suspend state should be passed
1436 * to device?
1437 */
1438 result = dev->driver->ops.resume(dev, 0);
1439 if (result) {
1440 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
1441 acpi_device_name(dev),
1442 acpi_device_bid(dev), result);
1443 }
1444 spin_lock(&acpi_device_lock);
1445 }
1446 }
1447 spin_unlock(&acpi_device_lock);
1448 return 0;
1449}
1450
1451
1452static int acpi_device_resume(struct device * dev)
1453{
1454 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1455
1456 /*
1457 * For now, we should only register 1 generic device -
1458 * the ACPI root device - and from there, we walk the
1459 * tree of ACPI devices to resume each one using the
1460 * ACPI driver methods.
1461 */
1462 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1463 root_resume(acpi_dev);
1464 return 0;
1465}
1466
1467
1468struct bus_type acpi_bus_type = {
1469 .name = "acpi",
1470 .suspend = acpi_device_suspend,
1471 .resume = acpi_device_resume,
1472};
1473
1474
1475
1374static int __init acpi_scan_init(void) 1476static int __init acpi_scan_init(void)
1375{ 1477{
1376 int result; 1478 int result;
@@ -1383,6 +1485,12 @@ static int __init acpi_scan_init(void)
1383 1485
1384 kset_register(&acpi_namespace_kset); 1486 kset_register(&acpi_namespace_kset);
1385 1487
1488 result = bus_register(&acpi_bus_type);
1489 if (result) {
1490 /* We don't want to quit even if we failed to add suspend/resume */
1491 printk(KERN_ERR PREFIX "Could not register bus type\n");
1492 }
1493
1386 /* 1494 /*
1387 * Create the root device in the bus's device tree 1495 * Create the root device in the bus's device tree
1388 */ 1496 */
@@ -1392,6 +1500,16 @@ static int __init acpi_scan_init(void)
1392 goto Done; 1500 goto Done;
1393 1501
1394 result = acpi_start_single_object(acpi_root); 1502 result = acpi_start_single_object(acpi_root);
1503 if (result)
1504 goto Done;
1505
1506 acpi_root->dev.bus = &acpi_bus_type;
1507 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1508 result = device_register(&acpi_root->dev);
1509 if (result) {
1510 /* We don't want to quit even if we failed to add suspend/resume */
1511 printk(KERN_ERR PREFIX "Could not register device\n");
1512 }
1395 1513
1396 /* 1514 /*
1397 * Enumerate devices in the ACPI namespace. 1515 * Enumerate devices in the ACPI namespace.
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 6dca3d542080..0de199aa6b94 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -26,7 +26,7 @@
26#ifndef __ACPI_BUS_H__ 26#ifndef __ACPI_BUS_H__
27#define __ACPI_BUS_H__ 27#define __ACPI_BUS_H__
28 28
29#include <linux/kobject.h> 29#include <linux/device.h>
30 30
31#include <acpi/acpi.h> 31#include <acpi/acpi.h>
32 32
@@ -296,6 +296,7 @@ struct acpi_device {
296 struct acpi_driver *driver; 296 struct acpi_driver *driver;
297 void *driver_data; 297 void *driver_data;
298 struct kobject kobj; 298 struct kobject kobj;
299 struct device dev;
299}; 300};
300 301
301#define acpi_driver_data(d) ((d)->driver_data) 302#define acpi_driver_data(d) ((d)->driver_data)