Skip to content

Commit

Permalink
[PATCH] Driver core: hande sysdev suspend failure
Browse files Browse the repository at this point in the history
This patch adds the return value check for sysdev suspend and does
restore in failure case. Send the patch to pm-list, but seems lost, so I
resend it.

Signed-off-by: Shaohua Li<shaohua.li@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Shaohua Li authored and Greg Kroah-Hartman committed Sep 5, 2005
1 parent 91e4900 commit ceaeade
Showing 1 changed file with 85 additions and 25 deletions.
110 changes: 85 additions & 25 deletions drivers/base/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,27 @@ void sysdev_shutdown(void)
up(&sysdev_drivers_lock);
}

static void __sysdev_resume(struct sys_device *dev)
{
struct sysdev_class *cls = dev->cls;
struct sysdev_driver *drv;

/* First, call the class-specific one */
if (cls->resume)
cls->resume(dev);

/* Call auxillary drivers next. */
list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->resume)
drv->resume(dev);
}

/* Call global drivers. */
list_for_each_entry(drv, &sysdev_drivers, entry) {
if (drv->resume)
drv->resume(dev);
}
}

/**
* sysdev_suspend - Suspend all system devices.
Expand All @@ -305,38 +326,93 @@ void sysdev_shutdown(void)
int sysdev_suspend(pm_message_t state)
{
struct sysdev_class * cls;
struct sys_device *sysdev, *err_dev;
struct sysdev_driver *drv, *err_drv;
int ret;

pr_debug("Suspending System Devices\n");

list_for_each_entry_reverse(cls, &system_subsys.kset.list,
kset.kobj.entry) {
struct sys_device * sysdev;

pr_debug("Suspending type '%s':\n",
kobject_name(&cls->kset.kobj));

list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));

/* Call global drivers first. */
list_for_each_entry(drv, &sysdev_drivers, entry) {
if (drv->suspend)
drv->suspend(sysdev, state);
if (drv->suspend) {
ret = drv->suspend(sysdev, state);
if (ret)
goto gbl_driver;
}
}

/* Call auxillary drivers next. */
list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->suspend)
drv->suspend(sysdev, state);
if (drv->suspend) {
ret = drv->suspend(sysdev, state);
if (ret)
goto aux_driver;
}
}

/* Now call the generic one */
if (cls->suspend)
cls->suspend(sysdev, state);
if (cls->suspend) {
ret = cls->suspend(sysdev, state);
if (ret)
goto cls_driver;
}
}
}
return 0;
/* resume current sysdev */
cls_driver:
drv = NULL;
printk(KERN_ERR "Class suspend failed for %s\n",
kobject_name(&sysdev->kobj));

aux_driver:
if (drv)
printk(KERN_ERR "Class driver suspend failed for %s\n",
kobject_name(&sysdev->kobj));
list_for_each_entry(err_drv, &cls->drivers, entry) {
if (err_drv == drv)
break;
if (err_drv->resume)
err_drv->resume(sysdev);
}
drv = NULL;

gbl_driver:
if (drv)
printk(KERN_ERR "sysdev driver suspend failed for %s\n",
kobject_name(&sysdev->kobj));
list_for_each_entry(err_drv, &sysdev_drivers, entry) {
if (err_drv == drv)
break;
if (err_drv->resume)
err_drv->resume(sysdev);
}
/* resume other sysdevs in current class */
list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
if (err_dev == sysdev)
break;
pr_debug(" %s\n", kobject_name(&err_dev->kobj));
__sysdev_resume(err_dev);
}

/* resume other classes */
list_for_each_entry_continue(cls, &system_subsys.kset.list,
kset.kobj.entry) {
list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
pr_debug(" %s\n", kobject_name(&err_dev->kobj));
__sysdev_resume(err_dev);
}
}
return ret;
}


Expand All @@ -362,25 +438,9 @@ int sysdev_resume(void)
kobject_name(&cls->kset.kobj));

list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
struct sysdev_driver * drv;
pr_debug(" %s\n", kobject_name(&sysdev->kobj));

/* First, call the class-specific one */
if (cls->resume)
cls->resume(sysdev);

/* Call auxillary drivers next. */
list_for_each_entry(drv, &cls->drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}

/* Call global drivers. */
list_for_each_entry(drv, &sysdev_drivers, entry) {
if (drv->resume)
drv->resume(sysdev);
}

__sysdev_resume(sysdev);
}
}
return 0;
Expand Down

0 comments on commit ceaeade

Please sign in to comment.