Loading arch/s390/include/asm/ccwgroup.h +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ struct ccwgroup_device { * @set_online: function called when device is set online * @set_offline: function called when device is set offline * @shutdown: function called when device is shut down * @prepare: prepare for pm state transition * @complete: undo work done in @prepare * @freeze: callback for freezing during hibernation snapshotting * @thaw: undo work done in @freeze * @restore: callback for restoring after hibernation * @driver: embedded driver structure */ struct ccwgroup_driver { Loading @@ -51,6 +56,11 @@ struct ccwgroup_driver { int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); void (*shutdown)(struct ccwgroup_device *); int (*prepare) (struct ccwgroup_device *); void (*complete) (struct ccwgroup_device *); int (*freeze)(struct ccwgroup_device *); int (*thaw) (struct ccwgroup_device *); int (*restore)(struct ccwgroup_device *); struct device_driver driver; }; Loading drivers/s390/cio/ccwgroup.c +73 −5 Original line number Diff line number Diff line /* * drivers/s390/cio/ccwgroup.c * bus driver for ccwgroup * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation * Copyright IBM Corp. 2002, 2009 * * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) */ Loading Loading @@ -501,6 +500,74 @@ static void ccwgroup_shutdown(struct device *dev) gdrv->shutdown(gdev); } static int ccwgroup_pm_prepare(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); /* Fail while device is being set online/offline. */ if (atomic_read(&gdev->onoff)) return -EAGAIN; if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->prepare ? gdrv->prepare(gdev) : 0; } static void ccwgroup_pm_complete(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return; if (gdrv->complete) gdrv->complete(gdev); } static int ccwgroup_pm_freeze(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->freeze ? gdrv->freeze(gdev) : 0; } static int ccwgroup_pm_thaw(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->thaw ? gdrv->thaw(gdev) : 0; } static int ccwgroup_pm_restore(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->restore ? gdrv->restore(gdev) : 0; } static struct dev_pm_ops ccwgroup_pm_ops = { .prepare = ccwgroup_pm_prepare, .complete = ccwgroup_pm_complete, .freeze = ccwgroup_pm_freeze, .thaw = ccwgroup_pm_thaw, .restore = ccwgroup_pm_restore, }; static struct bus_type ccwgroup_bus_type = { .name = "ccwgroup", .match = ccwgroup_bus_match, Loading @@ -508,6 +575,7 @@ static struct bus_type ccwgroup_bus_type = { .probe = ccwgroup_probe, .remove = ccwgroup_remove, .shutdown = ccwgroup_shutdown, .pm = &ccwgroup_pm_ops, }; Loading Loading
arch/s390/include/asm/ccwgroup.h +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,11 @@ struct ccwgroup_device { * @set_online: function called when device is set online * @set_offline: function called when device is set offline * @shutdown: function called when device is shut down * @prepare: prepare for pm state transition * @complete: undo work done in @prepare * @freeze: callback for freezing during hibernation snapshotting * @thaw: undo work done in @freeze * @restore: callback for restoring after hibernation * @driver: embedded driver structure */ struct ccwgroup_driver { Loading @@ -51,6 +56,11 @@ struct ccwgroup_driver { int (*set_online) (struct ccwgroup_device *); int (*set_offline) (struct ccwgroup_device *); void (*shutdown)(struct ccwgroup_device *); int (*prepare) (struct ccwgroup_device *); void (*complete) (struct ccwgroup_device *); int (*freeze)(struct ccwgroup_device *); int (*thaw) (struct ccwgroup_device *); int (*restore)(struct ccwgroup_device *); struct device_driver driver; }; Loading
drivers/s390/cio/ccwgroup.c +73 −5 Original line number Diff line number Diff line /* * drivers/s390/cio/ccwgroup.c * bus driver for ccwgroup * * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, * IBM Corporation * Copyright IBM Corp. 2002, 2009 * * Author(s): Arnd Bergmann (arndb@de.ibm.com) * Cornelia Huck (cornelia.huck@de.ibm.com) */ Loading Loading @@ -501,6 +500,74 @@ static void ccwgroup_shutdown(struct device *dev) gdrv->shutdown(gdev); } static int ccwgroup_pm_prepare(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); /* Fail while device is being set online/offline. */ if (atomic_read(&gdev->onoff)) return -EAGAIN; if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->prepare ? gdrv->prepare(gdev) : 0; } static void ccwgroup_pm_complete(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return; if (gdrv->complete) gdrv->complete(gdev); } static int ccwgroup_pm_freeze(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->freeze ? gdrv->freeze(gdev) : 0; } static int ccwgroup_pm_thaw(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->thaw ? gdrv->thaw(gdev) : 0; } static int ccwgroup_pm_restore(struct device *dev) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE) return 0; return gdrv->restore ? gdrv->restore(gdev) : 0; } static struct dev_pm_ops ccwgroup_pm_ops = { .prepare = ccwgroup_pm_prepare, .complete = ccwgroup_pm_complete, .freeze = ccwgroup_pm_freeze, .thaw = ccwgroup_pm_thaw, .restore = ccwgroup_pm_restore, }; static struct bus_type ccwgroup_bus_type = { .name = "ccwgroup", .match = ccwgroup_bus_match, Loading @@ -508,6 +575,7 @@ static struct bus_type ccwgroup_bus_type = { .probe = ccwgroup_probe, .remove = ccwgroup_remove, .shutdown = ccwgroup_shutdown, .pm = &ccwgroup_pm_ops, }; Loading