aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c8
-rw-r--r--drivers/base/class.c39
-rw-r--r--drivers/base/core.c2
-rw-r--r--drivers/base/dd.c2
-rw-r--r--drivers/base/firmware_class.c79
-rw-r--r--drivers/base/node.c24
-rw-r--r--drivers/base/power/resume.c8
-rw-r--r--drivers/base/power/runtime.c8
-rw-r--r--drivers/base/power/suspend.c12
-rw-r--r--drivers/base/power/sysfs.c8
-rw-r--r--drivers/base/sys.c110
11 files changed, 215 insertions, 85 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index ab53832d57e5..17e96698410e 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -156,7 +156,9 @@ static ssize_t driver_unbind(struct device_driver *drv,
156 device_release_driver(dev); 156 device_release_driver(dev);
157 err = count; 157 err = count;
158 } 158 }
159 return err; 159 if (err)
160 return err;
161 return count;
160} 162}
161static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 163static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
162 164
@@ -358,7 +360,7 @@ int bus_add_device(struct device * dev)
358 if (bus) { 360 if (bus) {
359 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); 361 pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
360 device_attach(dev); 362 device_attach(dev);
361 klist_add_tail(&bus->klist_devices, &dev->knode_bus); 363 klist_add_tail(&dev->knode_bus, &bus->klist_devices);
362 error = device_add_attrs(bus, dev); 364 error = device_add_attrs(bus, dev);
363 if (!error) { 365 if (!error) {
364 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); 366 sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
@@ -446,7 +448,7 @@ int bus_add_driver(struct device_driver * drv)
446 } 448 }
447 449
448 driver_attach(drv); 450 driver_attach(drv);
449 klist_add_tail(&bus->klist_drivers, &drv->knode_bus); 451 klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
450 module_add_driver(drv->owner, drv); 452 module_add_driver(drv->owner, drv);
451 453
452 driver_add_attrs(bus, drv); 454 driver_add_attrs(bus, drv);
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 0154a1623b21..d164c32a97ad 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -299,10 +299,8 @@ static void class_dev_release(struct kobject * kobj)
299 299
300 pr_debug("device class '%s': release.\n", cd->class_id); 300 pr_debug("device class '%s': release.\n", cd->class_id);
301 301
302 if (cd->devt_attr) { 302 kfree(cd->devt_attr);
303 kfree(cd->devt_attr); 303 cd->devt_attr = NULL;
304 cd->devt_attr = NULL;
305 }
306 304
307 if (cls->release) 305 if (cls->release)
308 cls->release(cd); 306 cls->release(cd);
@@ -452,10 +450,29 @@ void class_device_initialize(struct class_device *class_dev)
452 INIT_LIST_HEAD(&class_dev->node); 450 INIT_LIST_HEAD(&class_dev->node);
453} 451}
454 452
453static char *make_class_name(struct class_device *class_dev)
454{
455 char *name;
456 int size;
457
458 size = strlen(class_dev->class->name) +
459 strlen(kobject_name(&class_dev->kobj)) + 2;
460
461 name = kmalloc(size, GFP_KERNEL);
462 if (!name)
463 return ERR_PTR(-ENOMEM);
464
465 strcpy(name, class_dev->class->name);
466 strcat(name, ":");
467 strcat(name, kobject_name(&class_dev->kobj));
468 return name;
469}
470
455int class_device_add(struct class_device *class_dev) 471int class_device_add(struct class_device *class_dev)
456{ 472{
457 struct class * parent = NULL; 473 struct class * parent = NULL;
458 struct class_interface * class_intf; 474 struct class_interface * class_intf;
475 char *class_name = NULL;
459 int error; 476 int error;
460 477
461 class_dev = class_device_get(class_dev); 478 class_dev = class_device_get(class_dev);
@@ -500,9 +517,13 @@ int class_device_add(struct class_device *class_dev)
500 } 517 }
501 518
502 class_device_add_attrs(class_dev); 519 class_device_add_attrs(class_dev);
503 if (class_dev->dev) 520 if (class_dev->dev) {
521 class_name = make_class_name(class_dev);
504 sysfs_create_link(&class_dev->kobj, 522 sysfs_create_link(&class_dev->kobj,
505 &class_dev->dev->kobj, "device"); 523 &class_dev->dev->kobj, "device");
524 sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
525 class_name);
526 }
506 527
507 /* notify any interfaces this device is now here */ 528 /* notify any interfaces this device is now here */
508 if (parent) { 529 if (parent) {
@@ -519,6 +540,7 @@ int class_device_add(struct class_device *class_dev)
519 if (error && parent) 540 if (error && parent)
520 class_put(parent); 541 class_put(parent);
521 class_device_put(class_dev); 542 class_device_put(class_dev);
543 kfree(class_name);
522 return error; 544 return error;
523} 545}
524 546
@@ -584,6 +606,7 @@ void class_device_del(struct class_device *class_dev)
584{ 606{
585 struct class * parent = class_dev->class; 607 struct class * parent = class_dev->class;
586 struct class_interface * class_intf; 608 struct class_interface * class_intf;
609 char *class_name = NULL;
587 610
588 if (parent) { 611 if (parent) {
589 down(&parent->sem); 612 down(&parent->sem);
@@ -594,8 +617,11 @@ void class_device_del(struct class_device *class_dev)
594 up(&parent->sem); 617 up(&parent->sem);
595 } 618 }
596 619
597 if (class_dev->dev) 620 if (class_dev->dev) {
621 class_name = make_class_name(class_dev);
598 sysfs_remove_link(&class_dev->kobj, "device"); 622 sysfs_remove_link(&class_dev->kobj, "device");
623 sysfs_remove_link(&class_dev->dev->kobj, class_name);
624 }
599 if (class_dev->devt_attr) 625 if (class_dev->devt_attr)
600 class_device_remove_file(class_dev, class_dev->devt_attr); 626 class_device_remove_file(class_dev, class_dev->devt_attr);
601 class_device_remove_attrs(class_dev); 627 class_device_remove_attrs(class_dev);
@@ -605,6 +631,7 @@ void class_device_del(struct class_device *class_dev)
605 631
606 if (parent) 632 if (parent)
607 class_put(parent); 633 class_put(parent);
634 kfree(class_name);
608} 635}
609 636
610void class_device_unregister(struct class_device *class_dev) 637void class_device_unregister(struct class_device *class_dev)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index efe03a024a5b..c8a33df00761 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -249,7 +249,7 @@ int device_add(struct device *dev)
249 if ((error = bus_add_device(dev))) 249 if ((error = bus_add_device(dev)))
250 goto BusError; 250 goto BusError;
251 if (parent) 251 if (parent)
252 klist_add_tail(&parent->klist_children, &dev->knode_parent); 252 klist_add_tail(&dev->knode_parent, &parent->klist_children);
253 253
254 /* notify platform of device entry */ 254 /* notify platform of device entry */
255 if (platform_notify) 255 if (platform_notify)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 16323f9cbff0..d5bbce38282f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -42,7 +42,7 @@ void device_bind_driver(struct device * dev)
42{ 42{
43 pr_debug("bound device '%s' to driver '%s'\n", 43 pr_debug("bound device '%s' to driver '%s'\n",
44 dev->bus_id, dev->driver->name); 44 dev->bus_id, dev->driver->name);
45 klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver); 45 klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
46 sysfs_create_link(&dev->driver->kobj, &dev->kobj, 46 sysfs_create_link(&dev->driver->kobj, &dev->kobj,
47 kobject_name(&dev->kobj)); 47 kobject_name(&dev->kobj));
48 sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); 48 sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 652281402c92..5bfa2e9a7c26 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -28,6 +28,7 @@ enum {
28 FW_STATUS_DONE, 28 FW_STATUS_DONE,
29 FW_STATUS_ABORT, 29 FW_STATUS_ABORT,
30 FW_STATUS_READY, 30 FW_STATUS_READY,
31 FW_STATUS_READY_NOHOTPLUG,
31}; 32};
32 33
33static int loading_timeout = 10; /* In seconds */ 34static int loading_timeout = 10; /* In seconds */
@@ -344,7 +345,7 @@ error_kfree:
344 345
345static int 346static int
346fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p, 347fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
347 const char *fw_name, struct device *device) 348 const char *fw_name, struct device *device, int hotplug)
348{ 349{
349 struct class_device *class_dev; 350 struct class_device *class_dev;
350 struct firmware_priv *fw_priv; 351 struct firmware_priv *fw_priv;
@@ -376,7 +377,10 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
376 goto error_unreg; 377 goto error_unreg;
377 } 378 }
378 379
379 set_bit(FW_STATUS_READY, &fw_priv->status); 380 if (hotplug)
381 set_bit(FW_STATUS_READY, &fw_priv->status);
382 else
383 set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
380 *class_dev_p = class_dev; 384 *class_dev_p = class_dev;
381 goto out; 385 goto out;
382 386
@@ -386,21 +390,9 @@ out:
386 return retval; 390 return retval;
387} 391}
388 392
389/** 393static int
390 * request_firmware: - request firmware to hotplug and wait for it 394_request_firmware(const struct firmware **firmware_p, const char *name,
391 * Description: 395 struct device *device, int hotplug)
392 * @firmware will be used to return a firmware image by the name
393 * of @name for device @device.
394 *
395 * Should be called from user context where sleeping is allowed.
396 *
397 * @name will be use as $FIRMWARE in the hotplug environment and
398 * should be distinctive enough not to be confused with any other
399 * firmware image for this or any other device.
400 **/
401int
402request_firmware(const struct firmware **firmware_p, const char *name,
403 struct device *device)
404{ 396{
405 struct class_device *class_dev; 397 struct class_device *class_dev;
406 struct firmware_priv *fw_priv; 398 struct firmware_priv *fw_priv;
@@ -419,22 +411,25 @@ request_firmware(const struct firmware **firmware_p, const char *name,
419 } 411 }
420 memset(firmware, 0, sizeof (*firmware)); 412 memset(firmware, 0, sizeof (*firmware));
421 413
422 retval = fw_setup_class_device(firmware, &class_dev, name, device); 414 retval = fw_setup_class_device(firmware, &class_dev, name, device,
415 hotplug);
423 if (retval) 416 if (retval)
424 goto error_kfree_fw; 417 goto error_kfree_fw;
425 418
426 fw_priv = class_get_devdata(class_dev); 419 fw_priv = class_get_devdata(class_dev);
427 420
428 if (loading_timeout > 0) { 421 if (hotplug) {
429 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 422 if (loading_timeout > 0) {
430 add_timer(&fw_priv->timeout); 423 fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
431 } 424 add_timer(&fw_priv->timeout);
432 425 }
433 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
434 wait_for_completion(&fw_priv->completion);
435 set_bit(FW_STATUS_DONE, &fw_priv->status);
436 426
437 del_timer_sync(&fw_priv->timeout); 427 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
428 wait_for_completion(&fw_priv->completion);
429 set_bit(FW_STATUS_DONE, &fw_priv->status);
430 del_timer_sync(&fw_priv->timeout);
431 } else
432 wait_for_completion(&fw_priv->completion);
438 433
439 down(&fw_lock); 434 down(&fw_lock);
440 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) { 435 if (!fw_priv->fw->size || test_bit(FW_STATUS_ABORT, &fw_priv->status)) {
@@ -455,6 +450,26 @@ out:
455} 450}
456 451
457/** 452/**
453 * request_firmware: - request firmware to hotplug and wait for it
454 * Description:
455 * @firmware will be used to return a firmware image by the name
456 * of @name for device @device.
457 *
458 * Should be called from user context where sleeping is allowed.
459 *
460 * @name will be use as $FIRMWARE in the hotplug environment and
461 * should be distinctive enough not to be confused with any other
462 * firmware image for this or any other device.
463 **/
464int
465request_firmware(const struct firmware **firmware_p, const char *name,
466 struct device *device)
467{
468 int hotplug = 1;
469 return _request_firmware(firmware_p, name, device, hotplug);
470}
471
472/**
458 * release_firmware: - release the resource associated with a firmware image 473 * release_firmware: - release the resource associated with a firmware image
459 **/ 474 **/
460void 475void
@@ -491,6 +506,7 @@ struct firmware_work {
491 struct device *device; 506 struct device *device;
492 void *context; 507 void *context;
493 void (*cont)(const struct firmware *fw, void *context); 508 void (*cont)(const struct firmware *fw, void *context);
509 int hotplug;
494}; 510};
495 511
496static int 512static int
@@ -503,7 +519,8 @@ request_firmware_work_func(void *arg)
503 return 0; 519 return 0;
504 } 520 }
505 daemonize("%s/%s", "firmware", fw_work->name); 521 daemonize("%s/%s", "firmware", fw_work->name);
506 request_firmware(&fw, fw_work->name, fw_work->device); 522 _request_firmware(&fw, fw_work->name, fw_work->device,
523 fw_work->hotplug);
507 fw_work->cont(fw, fw_work->context); 524 fw_work->cont(fw, fw_work->context);
508 release_firmware(fw); 525 release_firmware(fw);
509 module_put(fw_work->module); 526 module_put(fw_work->module);
@@ -518,6 +535,9 @@ request_firmware_work_func(void *arg)
518 * Asynchronous variant of request_firmware() for contexts where 535 * Asynchronous variant of request_firmware() for contexts where
519 * it is not possible to sleep. 536 * it is not possible to sleep.
520 * 537 *
538 * @hotplug invokes hotplug event to copy the firmware image if this flag
539 * is non-zero else the firmware copy must be done manually.
540 *
521 * @cont will be called asynchronously when the firmware request is over. 541 * @cont will be called asynchronously when the firmware request is over.
522 * 542 *
523 * @context will be passed over to @cont. 543 * @context will be passed over to @cont.
@@ -527,7 +547,7 @@ request_firmware_work_func(void *arg)
527 **/ 547 **/
528int 548int
529request_firmware_nowait( 549request_firmware_nowait(
530 struct module *module, 550 struct module *module, int hotplug,
531 const char *name, struct device *device, void *context, 551 const char *name, struct device *device, void *context,
532 void (*cont)(const struct firmware *fw, void *context)) 552 void (*cont)(const struct firmware *fw, void *context))
533{ 553{
@@ -548,6 +568,7 @@ request_firmware_nowait(
548 .device = device, 568 .device = device,
549 .context = context, 569 .context = context,
550 .cont = cont, 570 .cont = cont,
571 .hotplug = hotplug,
551 }; 572 };
552 573
553 ret = kernel_thread(request_firmware_work_func, fw_work, 574 ret = kernel_thread(request_firmware_work_func, fw_work,
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 904b27caf697..16c513aa4d48 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -39,13 +39,25 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
39 int n; 39 int n;
40 int nid = dev->id; 40 int nid = dev->id;
41 struct sysinfo i; 41 struct sysinfo i;
42 struct page_state ps;
42 unsigned long inactive; 43 unsigned long inactive;
43 unsigned long active; 44 unsigned long active;
44 unsigned long free; 45 unsigned long free;
45 46
46 si_meminfo_node(&i, nid); 47 si_meminfo_node(&i, nid);
48 get_page_state_node(&ps, nid);
47 __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid)); 49 __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid));
48 50
51 /* Check for negative values in these approximate counters */
52 if ((long)ps.nr_dirty < 0)
53 ps.nr_dirty = 0;
54 if ((long)ps.nr_writeback < 0)
55 ps.nr_writeback = 0;
56 if ((long)ps.nr_mapped < 0)
57 ps.nr_mapped = 0;
58 if ((long)ps.nr_slab < 0)
59 ps.nr_slab = 0;
60
49 n = sprintf(buf, "\n" 61 n = sprintf(buf, "\n"
50 "Node %d MemTotal: %8lu kB\n" 62 "Node %d MemTotal: %8lu kB\n"
51 "Node %d MemFree: %8lu kB\n" 63 "Node %d MemFree: %8lu kB\n"
@@ -55,7 +67,11 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
55 "Node %d HighTotal: %8lu kB\n" 67 "Node %d HighTotal: %8lu kB\n"
56 "Node %d HighFree: %8lu kB\n" 68 "Node %d HighFree: %8lu kB\n"
57 "Node %d LowTotal: %8lu kB\n" 69 "Node %d LowTotal: %8lu kB\n"
58 "Node %d LowFree: %8lu kB\n", 70 "Node %d LowFree: %8lu kB\n"
71 "Node %d Dirty: %8lu kB\n"
72 "Node %d Writeback: %8lu kB\n"
73 "Node %d Mapped: %8lu kB\n"
74 "Node %d Slab: %8lu kB\n",
59 nid, K(i.totalram), 75 nid, K(i.totalram),
60 nid, K(i.freeram), 76 nid, K(i.freeram),
61 nid, K(i.totalram - i.freeram), 77 nid, K(i.totalram - i.freeram),
@@ -64,7 +80,11 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
64 nid, K(i.totalhigh), 80 nid, K(i.totalhigh),
65 nid, K(i.freehigh), 81 nid, K(i.freehigh),
66 nid, K(i.totalram - i.totalhigh), 82 nid, K(i.totalram - i.totalhigh),
67 nid, K(i.freeram - i.freehigh)); 83 nid, K(i.freeram - i.freehigh),
84 nid, K(ps.nr_dirty),
85 nid, K(ps.nr_writeback),
86 nid, K(ps.nr_mapped),
87 nid, K(ps.nr_slab));
68 n += hugetlb_report_node_meminfo(nid, buf + n); 88 n += hugetlb_report_node_meminfo(nid, buf + n);
69 return n; 89 return n;
70} 90}
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index bdd96b03b885..0a7aa07b9a2a 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -26,11 +26,11 @@ int resume_device(struct device * dev)
26 26
27 down(&dev->sem); 27 down(&dev->sem);
28 if (dev->power.pm_parent 28 if (dev->power.pm_parent
29 && dev->power.pm_parent->power.power_state) { 29 && dev->power.pm_parent->power.power_state.event) {
30 dev_err(dev, "PM: resume from %d, parent %s still %d\n", 30 dev_err(dev, "PM: resume from %d, parent %s still %d\n",
31 dev->power.power_state, 31 dev->power.power_state.event,
32 dev->power.pm_parent->bus_id, 32 dev->power.pm_parent->bus_id,
33 dev->power.pm_parent->power.power_state); 33 dev->power.pm_parent->power.power_state.event);
34 } 34 }
35 if (dev->bus && dev->bus->resume) { 35 if (dev->bus && dev->bus->resume) {
36 dev_dbg(dev,"resuming\n"); 36 dev_dbg(dev,"resuming\n");
@@ -54,7 +54,7 @@ void dpm_resume(void)
54 list_add_tail(entry, &dpm_active); 54 list_add_tail(entry, &dpm_active);
55 55
56 up(&dpm_list_sem); 56 up(&dpm_list_sem);
57 if (!dev->power.prev_state) 57 if (!dev->power.prev_state.event)
58 resume_device(dev); 58 resume_device(dev);
59 down(&dpm_list_sem); 59 down(&dpm_list_sem);
60 put_device(dev); 60 put_device(dev);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index 325962d80191..e8f0519f5dfa 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -13,10 +13,10 @@
13static void runtime_resume(struct device * dev) 13static void runtime_resume(struct device * dev)
14{ 14{
15 dev_dbg(dev, "resuming\n"); 15 dev_dbg(dev, "resuming\n");
16 if (!dev->power.power_state) 16 if (!dev->power.power_state.event)
17 return; 17 return;
18 if (!resume_device(dev)) 18 if (!resume_device(dev))
19 dev->power.power_state = 0; 19 dev->power.power_state = PMSG_ON;
20} 20}
21 21
22 22
@@ -49,10 +49,10 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
49 int error = 0; 49 int error = 0;
50 50
51 down(&dpm_sem); 51 down(&dpm_sem);
52 if (dev->power.power_state == state) 52 if (dev->power.power_state.event == state.event)
53 goto Done; 53 goto Done;
54 54
55 if (dev->power.power_state) 55 if (dev->power.power_state.event)
56 runtime_resume(dev); 56 runtime_resume(dev);
57 57
58 if (!(error = suspend_device(dev, state))) 58 if (!(error = suspend_device(dev, state)))
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 2ccee3763acf..50501764d050 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -40,22 +40,22 @@ int suspend_device(struct device * dev, pm_message_t state)
40 int error = 0; 40 int error = 0;
41 41
42 down(&dev->sem); 42 down(&dev->sem);
43 if (dev->power.power_state) { 43 if (dev->power.power_state.event) {
44 dev_dbg(dev, "PM: suspend %d-->%d\n", 44 dev_dbg(dev, "PM: suspend %d-->%d\n",
45 dev->power.power_state, state); 45 dev->power.power_state.event, state.event);
46 } 46 }
47 if (dev->power.pm_parent 47 if (dev->power.pm_parent
48 && dev->power.pm_parent->power.power_state) { 48 && dev->power.pm_parent->power.power_state.event) {
49 dev_err(dev, 49 dev_err(dev,
50 "PM: suspend %d->%d, parent %s already %d\n", 50 "PM: suspend %d->%d, parent %s already %d\n",
51 dev->power.power_state, state, 51 dev->power.power_state.event, state.event,
52 dev->power.pm_parent->bus_id, 52 dev->power.pm_parent->bus_id,
53 dev->power.pm_parent->power.power_state); 53 dev->power.pm_parent->power.power_state.event);
54 } 54 }
55 55
56 dev->power.prev_state = dev->power.power_state; 56 dev->power.prev_state = dev->power.power_state;
57 57
58 if (dev->bus && dev->bus->suspend && !dev->power.power_state) { 58 if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) {
59 dev_dbg(dev, "suspending\n"); 59 dev_dbg(dev, "suspending\n");
60 error = dev->bus->suspend(dev, state); 60 error = dev->bus->suspend(dev, state);
61 } 61 }
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index f82b3df9545f..8d04fb435c17 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -26,19 +26,19 @@
26 26
27static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) 27static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf)
28{ 28{
29 return sprintf(buf, "%u\n", dev->power.power_state); 29 return sprintf(buf, "%u\n", dev->power.power_state.event);
30} 30}
31 31
32static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) 32static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n)
33{ 33{
34 u32 state; 34 pm_message_t state;
35 char * rest; 35 char * rest;
36 int error = 0; 36 int error = 0;
37 37
38 state = simple_strtoul(buf, &rest, 10); 38 state.event = simple_strtoul(buf, &rest, 10);
39 if (*rest) 39 if (*rest)
40 return -EINVAL; 40 return -EINVAL;
41 if (state) 41 if (state.event)
42 error = dpm_runtime_suspend(dev, state); 42 error = dpm_runtime_suspend(dev, state);
43 else 43 else
44 dpm_runtime_resume(dev); 44 dpm_runtime_resume(dev);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 214b96435409..3431eb6004c3 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -288,6 +288,27 @@ void sysdev_shutdown(void)
288 up(&sysdev_drivers_lock); 288 up(&sysdev_drivers_lock);
289} 289}
290 290
291static void __sysdev_resume(struct sys_device *dev)
292{
293 struct sysdev_class *cls = dev->cls;
294 struct sysdev_driver *drv;
295
296 /* First, call the class-specific one */
297 if (cls->resume)
298 cls->resume(dev);
299
300 /* Call auxillary drivers next. */
301 list_for_each_entry(drv, &cls->drivers, entry) {
302 if (drv->resume)
303 drv->resume(dev);
304 }
305
306 /* Call global drivers. */
307 list_for_each_entry(drv, &sysdev_drivers, entry) {
308 if (drv->resume)
309 drv->resume(dev);
310 }
311}
291 312
292/** 313/**
293 * sysdev_suspend - Suspend all system devices. 314 * sysdev_suspend - Suspend all system devices.
@@ -305,38 +326,93 @@ void sysdev_shutdown(void)
305int sysdev_suspend(pm_message_t state) 326int sysdev_suspend(pm_message_t state)
306{ 327{
307 struct sysdev_class * cls; 328 struct sysdev_class * cls;
329 struct sys_device *sysdev, *err_dev;
330 struct sysdev_driver *drv, *err_drv;
331 int ret;
308 332
309 pr_debug("Suspending System Devices\n"); 333 pr_debug("Suspending System Devices\n");
310 334
311 list_for_each_entry_reverse(cls, &system_subsys.kset.list, 335 list_for_each_entry_reverse(cls, &system_subsys.kset.list,
312 kset.kobj.entry) { 336 kset.kobj.entry) {
313 struct sys_device * sysdev;
314 337
315 pr_debug("Suspending type '%s':\n", 338 pr_debug("Suspending type '%s':\n",
316 kobject_name(&cls->kset.kobj)); 339 kobject_name(&cls->kset.kobj));
317 340
318 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { 341 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
319 struct sysdev_driver * drv;
320 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 342 pr_debug(" %s\n", kobject_name(&sysdev->kobj));
321 343
322 /* Call global drivers first. */ 344 /* Call global drivers first. */
323 list_for_each_entry(drv, &sysdev_drivers, entry) { 345 list_for_each_entry(drv, &sysdev_drivers, entry) {
324 if (drv->suspend) 346 if (drv->suspend) {
325 drv->suspend(sysdev, state); 347 ret = drv->suspend(sysdev, state);
348 if (ret)
349 goto gbl_driver;
350 }
326 } 351 }
327 352
328 /* Call auxillary drivers next. */ 353 /* Call auxillary drivers next. */
329 list_for_each_entry(drv, &cls->drivers, entry) { 354 list_for_each_entry(drv, &cls->drivers, entry) {
330 if (drv->suspend) 355 if (drv->suspend) {
331 drv->suspend(sysdev, state); 356 ret = drv->suspend(sysdev, state);
357 if (ret)
358 goto aux_driver;
359 }
332 } 360 }
333 361
334 /* Now call the generic one */ 362 /* Now call the generic one */
335 if (cls->suspend) 363 if (cls->suspend) {
336 cls->suspend(sysdev, state); 364 ret = cls->suspend(sysdev, state);
365 if (ret)
366 goto cls_driver;
367 }
337 } 368 }
338 } 369 }
339 return 0; 370 return 0;
371 /* resume current sysdev */
372cls_driver:
373 drv = NULL;
374 printk(KERN_ERR "Class suspend failed for %s\n",
375 kobject_name(&sysdev->kobj));
376
377aux_driver:
378 if (drv)
379 printk(KERN_ERR "Class driver suspend failed for %s\n",
380 kobject_name(&sysdev->kobj));
381 list_for_each_entry(err_drv, &cls->drivers, entry) {
382 if (err_drv == drv)
383 break;
384 if (err_drv->resume)
385 err_drv->resume(sysdev);
386 }
387 drv = NULL;
388
389gbl_driver:
390 if (drv)
391 printk(KERN_ERR "sysdev driver suspend failed for %s\n",
392 kobject_name(&sysdev->kobj));
393 list_for_each_entry(err_drv, &sysdev_drivers, entry) {
394 if (err_drv == drv)
395 break;
396 if (err_drv->resume)
397 err_drv->resume(sysdev);
398 }
399 /* resume other sysdevs in current class */
400 list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
401 if (err_dev == sysdev)
402 break;
403 pr_debug(" %s\n", kobject_name(&err_dev->kobj));
404 __sysdev_resume(err_dev);
405 }
406
407 /* resume other classes */
408 list_for_each_entry_continue(cls, &system_subsys.kset.list,
409 kset.kobj.entry) {
410 list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
411 pr_debug(" %s\n", kobject_name(&err_dev->kobj));
412 __sysdev_resume(err_dev);
413 }
414 }
415 return ret;
340} 416}
341 417
342 418
@@ -362,25 +438,9 @@ int sysdev_resume(void)
362 kobject_name(&cls->kset.kobj)); 438 kobject_name(&cls->kset.kobj));
363 439
364 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { 440 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
365 struct sysdev_driver * drv;
366 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 441 pr_debug(" %s\n", kobject_name(&sysdev->kobj));
367 442
368 /* First, call the class-specific one */ 443 __sysdev_resume(sysdev);
369 if (cls->resume)
370 cls->resume(sysdev);
371
372 /* Call auxillary drivers next. */
373 list_for_each_entry(drv, &cls->drivers, entry) {
374 if (drv->resume)
375 drv->resume(sysdev);
376 }
377
378 /* Call global drivers. */
379 list_for_each_entry(drv, &sysdev_drivers, entry) {
380 if (drv->resume)
381 drv->resume(sysdev);
382 }
383
384 } 444 }
385 } 445 }
386 return 0; 446 return 0;