diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2009-06-16 04:30:21 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-06-16 04:31:08 -0400 |
commit | 7e597a21a1470b12428cb0edd03c40986026451f (patch) | |
tree | cab1b5df9e586f96c6f976a5a25b34205e581530 | |
parent | 823d494ac11111064cf39abd4178ce299414c771 (diff) |
[S390] pm: ccwgroup bus power management callbacks
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/ccwgroup.h | 10 | ||||
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 78 |
2 files changed, 83 insertions, 5 deletions
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index a27f68985a79..c79c1e787b86 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h | |||
@@ -38,6 +38,11 @@ struct ccwgroup_device { | |||
38 | * @set_online: function called when device is set online | 38 | * @set_online: function called when device is set online |
39 | * @set_offline: function called when device is set offline | 39 | * @set_offline: function called when device is set offline |
40 | * @shutdown: function called when device is shut down | 40 | * @shutdown: function called when device is shut down |
41 | * @prepare: prepare for pm state transition | ||
42 | * @complete: undo work done in @prepare | ||
43 | * @freeze: callback for freezing during hibernation snapshotting | ||
44 | * @thaw: undo work done in @freeze | ||
45 | * @restore: callback for restoring after hibernation | ||
41 | * @driver: embedded driver structure | 46 | * @driver: embedded driver structure |
42 | */ | 47 | */ |
43 | struct ccwgroup_driver { | 48 | struct ccwgroup_driver { |
@@ -51,6 +56,11 @@ struct ccwgroup_driver { | |||
51 | int (*set_online) (struct ccwgroup_device *); | 56 | int (*set_online) (struct ccwgroup_device *); |
52 | int (*set_offline) (struct ccwgroup_device *); | 57 | int (*set_offline) (struct ccwgroup_device *); |
53 | void (*shutdown)(struct ccwgroup_device *); | 58 | void (*shutdown)(struct ccwgroup_device *); |
59 | int (*prepare) (struct ccwgroup_device *); | ||
60 | void (*complete) (struct ccwgroup_device *); | ||
61 | int (*freeze)(struct ccwgroup_device *); | ||
62 | int (*thaw) (struct ccwgroup_device *); | ||
63 | int (*restore)(struct ccwgroup_device *); | ||
54 | 64 | ||
55 | struct device_driver driver; | 65 | struct device_driver driver; |
56 | }; | 66 | }; |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 22ce765d537e..a5a62f1f7747 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/s390/cio/ccwgroup.c | ||
3 | * bus driver for ccwgroup | 2 | * bus driver for ccwgroup |
4 | * | 3 | * |
5 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, | 4 | * Copyright IBM Corp. 2002, 2009 |
6 | * IBM Corporation | 5 | * |
7 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) | 6 | * Author(s): Arnd Bergmann (arndb@de.ibm.com) |
8 | * Cornelia Huck (cornelia.huck@de.ibm.com) | 7 | * Cornelia Huck (cornelia.huck@de.ibm.com) |
9 | */ | 8 | */ |
10 | #include <linux/module.h> | 9 | #include <linux/module.h> |
11 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
@@ -501,6 +500,74 @@ static void ccwgroup_shutdown(struct device *dev) | |||
501 | gdrv->shutdown(gdev); | 500 | gdrv->shutdown(gdev); |
502 | } | 501 | } |
503 | 502 | ||
503 | static int ccwgroup_pm_prepare(struct device *dev) | ||
504 | { | ||
505 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
506 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); | ||
507 | |||
508 | /* Fail while device is being set online/offline. */ | ||
509 | if (atomic_read(&gdev->onoff)) | ||
510 | return -EAGAIN; | ||
511 | |||
512 | if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) | ||
513 | return 0; | ||
514 | |||
515 | return gdrv->prepare ? gdrv->prepare(gdev) : 0; | ||
516 | } | ||
517 | |||
518 | static void ccwgroup_pm_complete(struct device *dev) | ||
519 | { | ||
520 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
521 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); | ||
522 | |||
523 | if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) | ||
524 | return; | ||
525 | |||
526 | if (gdrv->complete) | ||
527 | gdrv->complete(gdev); | ||
528 | } | ||
529 | |||
530 | static int ccwgroup_pm_freeze(struct device *dev) | ||
531 | { | ||
532 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
533 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); | ||
534 | |||
535 | if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) | ||
536 | return 0; | ||
537 | |||
538 | return gdrv->freeze ? gdrv->freeze(gdev) : 0; | ||
539 | } | ||
540 | |||
541 | static int ccwgroup_pm_thaw(struct device *dev) | ||
542 | { | ||
543 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
544 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); | ||
545 | |||
546 | if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) | ||
547 | return 0; | ||
548 | |||
549 | return gdrv->thaw ? gdrv->thaw(gdev) : 0; | ||
550 | } | ||
551 | |||
552 | static int ccwgroup_pm_restore(struct device *dev) | ||
553 | { | ||
554 | struct ccwgroup_device *gdev = to_ccwgroupdev(dev); | ||
555 | struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); | ||
556 | |||
557 | if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) | ||
558 | return 0; | ||
559 | |||
560 | return gdrv->restore ? gdrv->restore(gdev) : 0; | ||
561 | } | ||
562 | |||
563 | static struct dev_pm_ops ccwgroup_pm_ops = { | ||
564 | .prepare = ccwgroup_pm_prepare, | ||
565 | .complete = ccwgroup_pm_complete, | ||
566 | .freeze = ccwgroup_pm_freeze, | ||
567 | .thaw = ccwgroup_pm_thaw, | ||
568 | .restore = ccwgroup_pm_restore, | ||
569 | }; | ||
570 | |||
504 | static struct bus_type ccwgroup_bus_type = { | 571 | static struct bus_type ccwgroup_bus_type = { |
505 | .name = "ccwgroup", | 572 | .name = "ccwgroup", |
506 | .match = ccwgroup_bus_match, | 573 | .match = ccwgroup_bus_match, |
@@ -508,6 +575,7 @@ static struct bus_type ccwgroup_bus_type = { | |||
508 | .probe = ccwgroup_probe, | 575 | .probe = ccwgroup_probe, |
509 | .remove = ccwgroup_remove, | 576 | .remove = ccwgroup_remove, |
510 | .shutdown = ccwgroup_shutdown, | 577 | .shutdown = ccwgroup_shutdown, |
578 | .pm = &ccwgroup_pm_ops, | ||
511 | }; | 579 | }; |
512 | 580 | ||
513 | 581 | ||