aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/attribute_container.c2
-rw-r--r--drivers/base/base.h12
-rw-r--r--drivers/base/class.c150
-rw-r--r--drivers/base/core.c21
-rw-r--r--drivers/base/cpu.c1
-rw-r--r--drivers/base/driver.c3
-rw-r--r--drivers/base/firmware.c3
-rw-r--r--drivers/base/init.c10
-rw-r--r--drivers/base/platform.c22
-rw-r--r--drivers/base/power/sysfs.c73
10 files changed, 222 insertions, 75 deletions
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 6b2eb6f39b4d..2a7d7ae83e1e 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -19,6 +19,8 @@
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/module.h> 20#include <linux/module.h>
21 21
22#include "base.h"
23
22/* This is a private structure used to tie the classdev and the 24/* This is a private structure used to tie the classdev and the
23 * container .. it should never be visible outside this file */ 25 * container .. it should never be visible outside this file */
24struct internal_container { 26struct internal_container {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 783752b68a9a..e3b548d46cff 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -1,3 +1,15 @@
1
2/* initialisation functions */
3
4extern int devices_init(void);
5extern int buses_init(void);
6extern int classes_init(void);
7extern int firmware_init(void);
8extern int platform_bus_init(void);
9extern int system_bus_init(void);
10extern int cpu_dev_init(void);
11extern int attribute_container_init(void);
12
1extern int bus_add_device(struct device * dev); 13extern int bus_add_device(struct device * dev);
2extern void bus_remove_device(struct device * dev); 14extern void bus_remove_device(struct device * dev);
3 15
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ce23dc8c18c5..c3e569730afe 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -99,7 +99,8 @@ struct class * class_get(struct class * cls)
99 99
100void class_put(struct class * cls) 100void class_put(struct class * cls)
101{ 101{
102 subsys_put(&cls->subsys); 102 if (cls)
103 subsys_put(&cls->subsys);
103} 104}
104 105
105 106
@@ -165,14 +166,25 @@ void class_unregister(struct class * cls)
165 166
166static void class_create_release(struct class *cls) 167static void class_create_release(struct class *cls)
167{ 168{
169 pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
168 kfree(cls); 170 kfree(cls);
169} 171}
170 172
171static void class_device_create_release(struct class_device *class_dev) 173static void class_device_create_release(struct class_device *class_dev)
172{ 174{
175 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
173 kfree(class_dev); 176 kfree(class_dev);
174} 177}
175 178
179/* needed to allow these devices to have parent class devices */
180static int class_device_create_hotplug(struct class_device *class_dev,
181 char **envp, int num_envp,
182 char *buffer, int buffer_size)
183{
184 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
185 return 0;
186}
187
176/** 188/**
177 * class_create - create a struct class structure 189 * class_create - create a struct class structure
178 * @owner: pointer to the module that is to "own" this struct class 190 * @owner: pointer to the module that is to "own" this struct class
@@ -301,10 +313,12 @@ static void class_dev_release(struct kobject * kobj)
301 kfree(cd->devt_attr); 313 kfree(cd->devt_attr);
302 cd->devt_attr = NULL; 314 cd->devt_attr = NULL;
303 315
304 if (cls->release) 316 if (cd->release)
317 cd->release(cd);
318 else if (cls->release)
305 cls->release(cd); 319 cls->release(cd);
306 else { 320 else {
307 printk(KERN_ERR "Device class '%s' does not have a release() function, " 321 printk(KERN_ERR "Class Device '%s' does not have a release() function, "
308 "it is broken and must be fixed.\n", 322 "it is broken and must be fixed.\n",
309 cd->class_id); 323 cd->class_id);
310 WARN_ON(1); 324 WARN_ON(1);
@@ -382,14 +396,18 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
382 buffer = &buffer[length]; 396 buffer = &buffer[length];
383 buffer_size -= length; 397 buffer_size -= length;
384 398
385 if (class_dev->class->hotplug) { 399 if (class_dev->hotplug) {
386 /* have the bus specific function add its stuff */ 400 /* have the class device specific function add its stuff */
387 retval = class_dev->class->hotplug (class_dev, envp, num_envp, 401 retval = class_dev->hotplug(class_dev, envp, num_envp,
388 buffer, buffer_size); 402 buffer, buffer_size);
389 if (retval) { 403 if (retval)
390 pr_debug ("%s - hotplug() returned %d\n", 404 pr_debug("class_dev->hotplug() returned %d\n", retval);
391 __FUNCTION__, retval); 405 } else if (class_dev->class->hotplug) {
392 } 406 /* have the class specific function add its stuff */
407 retval = class_dev->class->hotplug(class_dev, envp, num_envp,
408 buffer, buffer_size);
409 if (retval)
410 pr_debug("class->hotplug() returned %d\n", retval);
393 } 411 }
394 412
395 return retval; 413 return retval;
@@ -442,6 +460,13 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
442 return print_dev_t(buf, class_dev->devt); 460 return print_dev_t(buf, class_dev->devt);
443} 461}
444 462
463static ssize_t store_uevent(struct class_device *class_dev,
464 const char *buf, size_t count)
465{
466 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
467 return count;
468}
469
445void class_device_initialize(struct class_device *class_dev) 470void class_device_initialize(struct class_device *class_dev)
446{ 471{
447 kobj_set_kset_s(class_dev, class_obj_subsys); 472 kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -469,34 +494,45 @@ static char *make_class_name(struct class_device *class_dev)
469 494
470int class_device_add(struct class_device *class_dev) 495int class_device_add(struct class_device *class_dev)
471{ 496{
472 struct class * parent = NULL; 497 struct class *parent_class = NULL;
473 struct class_interface * class_intf; 498 struct class_device *parent_class_dev = NULL;
499 struct class_interface *class_intf;
474 char *class_name = NULL; 500 char *class_name = NULL;
475 int error; 501 int error = -EINVAL;
476 502
477 class_dev = class_device_get(class_dev); 503 class_dev = class_device_get(class_dev);
478 if (!class_dev) 504 if (!class_dev)
479 return -EINVAL; 505 return -EINVAL;
480 506
481 if (!strlen(class_dev->class_id)) { 507 if (!strlen(class_dev->class_id))
482 error = -EINVAL;
483 goto register_done; 508 goto register_done;
484 }
485 509
486 parent = class_get(class_dev->class); 510 parent_class = class_get(class_dev->class);
511 if (!parent_class)
512 goto register_done;
513 parent_class_dev = class_device_get(class_dev->parent);
487 514
488 pr_debug("CLASS: registering class device: ID = '%s'\n", 515 pr_debug("CLASS: registering class device: ID = '%s'\n",
489 class_dev->class_id); 516 class_dev->class_id);
490 517
491 /* first, register with generic layer. */ 518 /* first, register with generic layer. */
492 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 519 kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
493 if (parent) 520 if (parent_class_dev)
494 class_dev->kobj.parent = &parent->subsys.kset.kobj; 521 class_dev->kobj.parent = &parent_class_dev->kobj;
522 else
523 class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
495 524
496 if ((error = kobject_add(&class_dev->kobj))) 525 error = kobject_add(&class_dev->kobj);
526 if (error)
497 goto register_done; 527 goto register_done;
498 528
499 /* add the needed attributes to this device */ 529 /* add the needed attributes to this device */
530 class_dev->uevent_attr.attr.name = "uevent";
531 class_dev->uevent_attr.attr.mode = S_IWUSR;
532 class_dev->uevent_attr.attr.owner = parent_class->owner;
533 class_dev->uevent_attr.store = store_uevent;
534 class_device_create_file(class_dev, &class_dev->uevent_attr);
535
500 if (MAJOR(class_dev->devt)) { 536 if (MAJOR(class_dev->devt)) {
501 struct class_device_attribute *attr; 537 struct class_device_attribute *attr;
502 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 538 attr = kzalloc(sizeof(*attr), GFP_KERNEL);
@@ -505,12 +541,10 @@ int class_device_add(struct class_device *class_dev)
505 kobject_del(&class_dev->kobj); 541 kobject_del(&class_dev->kobj);
506 goto register_done; 542 goto register_done;
507 } 543 }
508
509 attr->attr.name = "dev"; 544 attr->attr.name = "dev";
510 attr->attr.mode = S_IRUGO; 545 attr->attr.mode = S_IRUGO;
511 attr->attr.owner = parent->owner; 546 attr->attr.owner = parent_class->owner;
512 attr->show = show_dev; 547 attr->show = show_dev;
513 attr->store = NULL;
514 class_device_create_file(class_dev, attr); 548 class_device_create_file(class_dev, attr);
515 class_dev->devt_attr = attr; 549 class_dev->devt_attr = attr;
516 } 550 }
@@ -524,20 +558,23 @@ int class_device_add(struct class_device *class_dev)
524 class_name); 558 class_name);
525 } 559 }
526 560
561 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
562
527 /* notify any interfaces this device is now here */ 563 /* notify any interfaces this device is now here */
528 if (parent) { 564 if (parent_class) {
529 down(&parent->sem); 565 down(&parent_class->sem);
530 list_add_tail(&class_dev->node, &parent->children); 566 list_add_tail(&class_dev->node, &parent_class->children);
531 list_for_each_entry(class_intf, &parent->interfaces, node) 567 list_for_each_entry(class_intf, &parent_class->interfaces, node)
532 if (class_intf->add) 568 if (class_intf->add)
533 class_intf->add(class_dev); 569 class_intf->add(class_dev, class_intf);
534 up(&parent->sem); 570 up(&parent_class->sem);
535 } 571 }
536 kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
537 572
538 register_done: 573 register_done:
539 if (error && parent) 574 if (error) {
540 class_put(parent); 575 class_put(parent_class);
576 class_device_put(parent_class_dev);
577 }
541 class_device_put(class_dev); 578 class_device_put(class_dev);
542 kfree(class_name); 579 kfree(class_name);
543 return error; 580 return error;
@@ -552,21 +589,28 @@ int class_device_register(struct class_device *class_dev)
552/** 589/**
553 * class_device_create - creates a class device and registers it with sysfs 590 * class_device_create - creates a class device and registers it with sysfs
554 * @cs: pointer to the struct class that this device should be registered to. 591 * @cs: pointer to the struct class that this device should be registered to.
592 * @parent: pointer to the parent struct class_device of this new device, if any.
555 * @dev: the dev_t for the char device to be added. 593 * @dev: the dev_t for the char device to be added.
556 * @device: a pointer to a struct device that is assiociated with this class device. 594 * @device: a pointer to a struct device that is assiociated with this class device.
557 * @fmt: string for the class device's name 595 * @fmt: string for the class device's name
558 * 596 *
559 * This function can be used by char device classes. A struct 597 * This function can be used by char device classes. A struct
560 * class_device will be created in sysfs, registered to the specified 598 * class_device will be created in sysfs, registered to the specified
561 * class. A "dev" file will be created, showing the dev_t for the 599 * class.
562 * device. The pointer to the struct class_device will be returned from 600 * A "dev" file will be created, showing the dev_t for the device, if
563 * the call. Any further sysfs files that might be required can be 601 * the dev_t is not 0,0.
564 * created using this pointer. 602 * If a pointer to a parent struct class_device is passed in, the newly
603 * created struct class_device will be a child of that device in sysfs.
604 * The pointer to the struct class_device will be returned from the
605 * call. Any further sysfs files that might be required can be created
606 * using this pointer.
565 * 607 *
566 * Note: the struct class passed to this function must have previously 608 * Note: the struct class passed to this function must have previously
567 * been created with a call to class_create(). 609 * been created with a call to class_create().
568 */ 610 */
569struct class_device *class_device_create(struct class *cls, dev_t devt, 611struct class_device *class_device_create(struct class *cls,
612 struct class_device *parent,
613 dev_t devt,
570 struct device *device, char *fmt, ...) 614 struct device *device, char *fmt, ...)
571{ 615{
572 va_list args; 616 va_list args;
@@ -585,6 +629,9 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
585 class_dev->devt = devt; 629 class_dev->devt = devt;
586 class_dev->dev = device; 630 class_dev->dev = device;
587 class_dev->class = cls; 631 class_dev->class = cls;
632 class_dev->parent = parent;
633 class_dev->release = class_device_create_release;
634 class_dev->hotplug = class_device_create_hotplug;
588 635
589 va_start(args, fmt); 636 va_start(args, fmt);
590 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); 637 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -602,17 +649,18 @@ error:
602 649
603void class_device_del(struct class_device *class_dev) 650void class_device_del(struct class_device *class_dev)
604{ 651{
605 struct class * parent = class_dev->class; 652 struct class *parent_class = class_dev->class;
606 struct class_interface * class_intf; 653 struct class_device *parent_device = class_dev->parent;
654 struct class_interface *class_intf;
607 char *class_name = NULL; 655 char *class_name = NULL;
608 656
609 if (parent) { 657 if (parent_class) {
610 down(&parent->sem); 658 down(&parent_class->sem);
611 list_del_init(&class_dev->node); 659 list_del_init(&class_dev->node);
612 list_for_each_entry(class_intf, &parent->interfaces, node) 660 list_for_each_entry(class_intf, &parent_class->interfaces, node)
613 if (class_intf->remove) 661 if (class_intf->remove)
614 class_intf->remove(class_dev); 662 class_intf->remove(class_dev, class_intf);
615 up(&parent->sem); 663 up(&parent_class->sem);
616 } 664 }
617 665
618 if (class_dev->dev) { 666 if (class_dev->dev) {
@@ -620,6 +668,7 @@ void class_device_del(struct class_device *class_dev)
620 sysfs_remove_link(&class_dev->kobj, "device"); 668 sysfs_remove_link(&class_dev->kobj, "device");
621 sysfs_remove_link(&class_dev->dev->kobj, class_name); 669 sysfs_remove_link(&class_dev->dev->kobj, class_name);
622 } 670 }
671 class_device_remove_file(class_dev, &class_dev->uevent_attr);
623 if (class_dev->devt_attr) 672 if (class_dev->devt_attr)
624 class_device_remove_file(class_dev, class_dev->devt_attr); 673 class_device_remove_file(class_dev, class_dev->devt_attr);
625 class_device_remove_attrs(class_dev); 674 class_device_remove_attrs(class_dev);
@@ -627,8 +676,8 @@ void class_device_del(struct class_device *class_dev)
627 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE); 676 kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
628 kobject_del(&class_dev->kobj); 677 kobject_del(&class_dev->kobj);
629 678
630 if (parent) 679 class_device_put(parent_device);
631 class_put(parent); 680 class_put(parent_class);
632 kfree(class_name); 681 kfree(class_name);
633} 682}
634 683
@@ -708,7 +757,8 @@ struct class_device * class_device_get(struct class_device *class_dev)
708 757
709void class_device_put(struct class_device *class_dev) 758void class_device_put(struct class_device *class_dev)
710{ 759{
711 kobject_put(&class_dev->kobj); 760 if (class_dev)
761 kobject_put(&class_dev->kobj);
712} 762}
713 763
714 764
@@ -728,7 +778,7 @@ int class_interface_register(struct class_interface *class_intf)
728 list_add_tail(&class_intf->node, &parent->interfaces); 778 list_add_tail(&class_intf->node, &parent->interfaces);
729 if (class_intf->add) { 779 if (class_intf->add) {
730 list_for_each_entry(class_dev, &parent->children, node) 780 list_for_each_entry(class_dev, &parent->children, node)
731 class_intf->add(class_dev); 781 class_intf->add(class_dev, class_intf);
732 } 782 }
733 up(&parent->sem); 783 up(&parent->sem);
734 784
@@ -747,7 +797,7 @@ void class_interface_unregister(struct class_interface *class_intf)
747 list_del_init(&class_intf->node); 797 list_del_init(&class_intf->node);
748 if (class_intf->remove) { 798 if (class_intf->remove) {
749 list_for_each_entry(class_dev, &parent->children, node) 799 list_for_each_entry(class_dev, &parent->children, node)
750 class_intf->remove(class_dev); 800 class_intf->remove(class_dev, class_intf);
751 } 801 }
752 up(&parent->sem); 802 up(&parent->sem);
753 803
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6ab73f5c799a..8615b42b517a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = {
154 .hotplug = dev_hotplug, 154 .hotplug = dev_hotplug,
155}; 155};
156 156
157static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
158 const char *buf, size_t count)
159{
160 kobject_hotplug(&dev->kobj, KOBJ_ADD);
161 return count;
162}
163
157/** 164/**
158 * device_subsys - structure to be registered with kobject core. 165 * device_subsys - structure to be registered with kobject core.
159 */ 166 */
@@ -225,6 +232,7 @@ void device_initialize(struct device *dev)
225 klist_children_put); 232 klist_children_put);
226 INIT_LIST_HEAD(&dev->dma_pools); 233 INIT_LIST_HEAD(&dev->dma_pools);
227 init_MUTEX(&dev->sem); 234 init_MUTEX(&dev->sem);
235 device_init_wakeup(dev, 0);
228} 236}
229 237
230/** 238/**
@@ -258,6 +266,14 @@ int device_add(struct device *dev)
258 266
259 if ((error = kobject_add(&dev->kobj))) 267 if ((error = kobject_add(&dev->kobj)))
260 goto Error; 268 goto Error;
269
270 dev->uevent_attr.attr.name = "uevent";
271 dev->uevent_attr.attr.mode = S_IWUSR;
272 if (dev->driver)
273 dev->uevent_attr.attr.owner = dev->driver->owner;
274 dev->uevent_attr.store = store_uevent;
275 device_create_file(dev, &dev->uevent_attr);
276
261 kobject_hotplug(&dev->kobj, KOBJ_ADD); 277 kobject_hotplug(&dev->kobj, KOBJ_ADD);
262 if ((error = device_pm_add(dev))) 278 if ((error = device_pm_add(dev)))
263 goto PMError; 279 goto PMError;
@@ -349,6 +365,7 @@ void device_del(struct device * dev)
349 365
350 if (parent) 366 if (parent)
351 klist_del(&dev->knode_parent); 367 klist_del(&dev->knode_parent);
368 device_remove_file(dev, &dev->uevent_attr);
352 369
353 /* Notify the platform of the removal, in case they 370 /* Notify the platform of the removal, in case they
354 * need to do anything... 371 * need to do anything...
@@ -390,11 +407,11 @@ static struct device * next_device(struct klist_iter * i)
390 407
391/** 408/**
392 * device_for_each_child - device child iterator. 409 * device_for_each_child - device child iterator.
393 * @dev: parent struct device. 410 * @parent: parent struct device.
394 * @data: data for the callback. 411 * @data: data for the callback.
395 * @fn: function to be called for each device. 412 * @fn: function to be called for each device.
396 * 413 *
397 * Iterate over @dev's child devices, and call @fn for each, 414 * Iterate over @parent's child devices, and call @fn for each,
398 * passing it @data. 415 * passing it @data.
399 * 416 *
400 * We check the return of @fn each time. If it returns anything 417 * We check the return of @fn each time. If it returns anything
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index b79badd0f158..081c927b1ed8 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -9,6 +9,7 @@
9#include <linux/topology.h> 9#include <linux/topology.h>
10#include <linux/device.h> 10#include <linux/device.h>
11 11
12#include "base.h"
12 13
13struct sysdev_class cpu_sysdev_class = { 14struct sysdev_class cpu_sysdev_class = {
14 set_kset_name("cpu"), 15 set_kset_name("cpu"),
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index ef3fe513e398..161f3a390d90 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i)
28/** 28/**
29 * driver_for_each_device - Iterator for devices bound to a driver. 29 * driver_for_each_device - Iterator for devices bound to a driver.
30 * @drv: Driver we're iterating. 30 * @drv: Driver we're iterating.
31 * @start: Device to begin with
31 * @data: Data to pass to the callback. 32 * @data: Data to pass to the callback.
32 * @fn: Function to call for each device. 33 * @fn: Function to call for each device.
33 * 34 *
@@ -57,7 +58,7 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
57 58
58/** 59/**
59 * driver_find_device - device iterator for locating a particular device. 60 * driver_find_device - device iterator for locating a particular device.
60 * @driver: The device's driver 61 * @drv: The device's driver
61 * @start: Device to begin with 62 * @start: Device to begin with
62 * @data: Data to pass to match function 63 * @data: Data to pass to match function
63 * @match: Callback function to check device 64 * @match: Callback function to check device
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
index 88ab044932f2..cb1b98ae0d58 100644
--- a/drivers/base/firmware.c
+++ b/drivers/base/firmware.c
@@ -11,6 +11,9 @@
11#include <linux/kobject.h> 11#include <linux/kobject.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/device.h>
15
16#include "base.h"
14 17
15static decl_subsys(firmware, NULL, NULL); 18static decl_subsys(firmware, NULL, NULL);
16 19
diff --git a/drivers/base/init.c b/drivers/base/init.c
index a76ae5a221f3..84e604e25c4f 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -10,14 +10,8 @@
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/init.h> 11#include <linux/init.h>
12 12
13extern int devices_init(void); 13#include "base.h"
14extern int buses_init(void); 14
15extern int classes_init(void);
16extern int firmware_init(void);
17extern int platform_bus_init(void);
18extern int system_bus_init(void);
19extern int cpu_dev_init(void);
20extern int attribute_container_init(void);
21/** 15/**
22 * driver_init - initialize driver model. 16 * driver_init - initialize driver model.
23 * 17 *
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 361e204209eb..75ce8711bca5 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -17,6 +17,8 @@
17#include <linux/bootmem.h> 17#include <linux/bootmem.h>
18#include <linux/err.h> 18#include <linux/err.h>
19 19
20#include "base.h"
21
20struct device platform_bus = { 22struct device platform_bus = {
21 .bus_id = "platform", 23 .bus_id = "platform",
22}; 24};
@@ -279,13 +281,9 @@ static int platform_suspend(struct device * dev, pm_message_t state)
279{ 281{
280 int ret = 0; 282 int ret = 0;
281 283
282 if (dev->driver && dev->driver->suspend) { 284 if (dev->driver && dev->driver->suspend)
283 ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE); 285 ret = dev->driver->suspend(dev, state);
284 if (ret == 0) 286
285 ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
286 if (ret == 0)
287 ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
288 }
289 return ret; 287 return ret;
290} 288}
291 289
@@ -293,13 +291,9 @@ static int platform_resume(struct device * dev)
293{ 291{
294 int ret = 0; 292 int ret = 0;
295 293
296 if (dev->driver && dev->driver->resume) { 294 if (dev->driver && dev->driver->resume)
297 ret = dev->driver->resume(dev, RESUME_POWER_ON); 295 ret = dev->driver->resume(dev);
298 if (ret == 0) 296
299 ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
300 if (ret == 0)
301 ret = dev->driver->resume(dev, RESUME_ENABLE);
302 }
303 return ret; 297 return ret;
304} 298}
305 299
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 8d04fb435c17..89c57875f3e5 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -48,8 +48,81 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c
48static DEVICE_ATTR(state, 0644, state_show, state_store); 48static DEVICE_ATTR(state, 0644, state_show, state_store);
49 49
50 50
51/*
52 * wakeup - Report/change current wakeup option for device
53 *
54 * Some devices support "wakeup" events, which are hardware signals
55 * used to activate devices from suspended or low power states. Such
56 * devices have one of three values for the sysfs power/wakeup file:
57 *
58 * + "enabled\n" to issue the events;
59 * + "disabled\n" not to do so; or
60 * + "\n" for temporary or permanent inability to issue wakeup.
61 *
62 * (For example, unconfigured USB devices can't issue wakeups.)
63 *
64 * Familiar examples of devices that can issue wakeup events include
65 * keyboards and mice (both PS2 and USB styles), power buttons, modems,
66 * "Wake-On-LAN" Ethernet links, GPIO lines, and more. Some events
67 * will wake the entire system from a suspend state; others may just
68 * wake up the device (if the system as a whole is already active).
69 * Some wakeup events use normal IRQ lines; other use special out
70 * of band signaling.
71 *
72 * It is the responsibility of device drivers to enable (or disable)
73 * wakeup signaling as part of changing device power states, respecting
74 * the policy choices provided through the driver model.
75 *
76 * Devices may not be able to generate wakeup events from all power
77 * states. Also, the events may be ignored in some configurations;
78 * for example, they might need help from other devices that aren't
79 * active, or which may have wakeup disabled. Some drivers rely on
80 * wakeup events internally (unless they are disabled), keeping
81 * their hardware in low power modes whenever they're unused. This
82 * saves runtime power, without requiring system-wide sleep states.
83 */
84
85static const char enabled[] = "enabled";
86static const char disabled[] = "disabled";
87
88static ssize_t
89wake_show(struct device * dev, struct device_attribute *attr, char * buf)
90{
91 return sprintf(buf, "%s\n", device_can_wakeup(dev)
92 ? (device_may_wakeup(dev) ? enabled : disabled)
93 : "");
94}
95
96static ssize_t
97wake_store(struct device * dev, struct device_attribute *attr,
98 const char * buf, size_t n)
99{
100 char *cp;
101 int len = n;
102
103 if (!device_can_wakeup(dev))
104 return -EINVAL;
105
106 cp = memchr(buf, '\n', n);
107 if (cp)
108 len = cp - buf;
109 if (len == sizeof enabled - 1
110 && strncmp(buf, enabled, sizeof enabled - 1) == 0)
111 device_set_wakeup_enable(dev, 1);
112 else if (len == sizeof disabled - 1
113 && strncmp(buf, disabled, sizeof disabled - 1) == 0)
114 device_set_wakeup_enable(dev, 0);
115 else
116 return -EINVAL;
117 return n;
118}
119
120static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
121
122
51static struct attribute * power_attrs[] = { 123static struct attribute * power_attrs[] = {
52 &dev_attr_state.attr, 124 &dev_attr_state.attr,
125 &dev_attr_wakeup.attr,
53 NULL, 126 NULL,
54}; 127};
55static struct attribute_group pm_attr_group = { 128static struct attribute_group pm_attr_group = {