diff options
| author | Dave Jones <davej@codemonkey.org.uk> | 2002-10-07 20:13:56 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-07 20:13:56 -0700 |
| commit | 081873a5f6bb62f0d75a5388e09db7cbca9034da (patch) | |
| tree | 988e1dab510c108479615943c10e8258322b8915 /drivers/base | |
| parent | b1c89e90bff7ffc1bd7d78e0e586a4b71350f813 (diff) | |
[PATCH] Remove code duplication in power.c
As per the FIXME. Work done by Eric Blade
Diffstat (limited to 'drivers/base')
| -rw-r--r-- | drivers/base/power.c | 60 |
1 files changed, 22 insertions, 38 deletions
diff --git a/drivers/base/power.c b/drivers/base/power.c index 8161725356ca..c98984dfd8ab 100644 --- a/drivers/base/power.c +++ b/drivers/base/power.c @@ -6,8 +6,6 @@ * * Kai Germaschewski contributed to the list walking routines. * - * FIXME: The suspend and shutdown walks are identical. The resume walk - * is simply walking the list backward. Anyway we can combine these (cleanly)? */ #include <linux/device.h> @@ -17,13 +15,15 @@ #define to_dev(node) container_of(node,struct device,g_list) /** - * device_suspend - suspend all devices on the device tree + * device_suspend - suspend/remove all devices on the device ree * @state: state we're entering - * @level: what stage of the suspend process we're at - * - * The entries in the global device list are inserted such that they're in a - * depth-first ordering. So, simply iterate over the list, and call the driver's - * suspend callback for each device. + * @level: what stage of the suspend process we're at + * (emb: it seems that these two arguments are described backwards of what + * they actually mean .. is this correct?) + * + * The entries in the global device list are inserted such that they're in a + * depth-first ordering. So, simply interate over the list, and call the + * driver's suspend or remove callback for each device. */ int device_suspend(u32 state, u32 level) { @@ -31,15 +31,23 @@ int device_suspend(u32 state, u32 level) struct device * prev = NULL; int error = 0; - printk(KERN_EMERG "Suspending Devices\n"); + if(level == SUSPEND_POWER_DOWN) + printk(KERN_EMERG "Shutting down devices\n"); + else + printk(KERN_EMERG "Suspending devices\n"); spin_lock(&device_lock); list_for_each(node,&global_device_list) { struct device * dev = get_device_locked(to_dev(node)); if (dev) { spin_unlock(&device_lock); - if (dev->driver && dev->driver->suspend) - error = dev->driver->suspend(dev,state,level); + if(dev->driver) { + if(level == SUSPEND_POWER_DOWN) { + if(dev->driver->remove) + dev->driver->remove(dev); + } else if(dev->driver->suspend) + error = dev->driver->suspend(dev,state,level); + } if (prev) put_device(prev); prev = dev; @@ -83,36 +91,12 @@ void device_resume(u32 level) } /** - * device_shutdown - queisce all the devices before reboot/shutdown - * - * Do depth first iteration over device tree, calling ->remove() for each - * device. This should ensure the devices are put into a sane state before - * we reboot the system. - * + * device_shutdown - call device_suspend with status set to shutdown, to + * cause all devices to remove themselves cleanly */ void device_shutdown(void) { - struct list_head * node, * next; - struct device * prev = NULL; - - printk(KERN_EMERG "Shutting down devices\n"); - - spin_lock(&device_lock); - list_for_each_safe(node,next,&global_device_list) { - struct device * dev = get_device_locked(to_dev(node)); - if (dev) { - spin_unlock(&device_lock); - if (dev->driver && dev->driver->remove) - dev->driver->remove(dev); - if (prev) - put_device(prev); - prev = dev; - spin_lock(&device_lock); - } - } - spin_unlock(&device_lock); - if (prev) - put_device(prev); + device_suspend(4, SUSPEND_POWER_DOWN); } EXPORT_SYMBOL(device_suspend); |
