Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
new file mode 100644
index 0000000..a0b5cf6
--- /dev/null
+++ b/drivers/base/power/suspend.c
@@ -0,0 +1,144 @@
+/*
+ * suspend.c - Functions for putting devices to sleep.
+ *
+ * Copyright (c) 2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Labs
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <linux/device.h>
+#include "power.h"
+
+extern int sysdev_suspend(pm_message_t state);
+
+/*
+ * The entries in the dpm_active list are in a depth first order, simply
+ * because children are guaranteed to be discovered after parents, and
+ * are inserted at the back of the list on discovery.
+ *
+ * All list on the suspend path are done in reverse order, so we operate
+ * on the leaves of the device tree (or forests, depending on how you want
+ * to look at it ;) first. As nodes are removed from the back of the list,
+ * they are inserted into the front of their destintation lists.
+ *
+ * Things are the reverse on the resume path - iterations are done in
+ * forward order, and nodes are inserted at the back of their destination
+ * lists. This way, the ancestors will be accessed before their descendents.
+ */
+
+
+/**
+ *	suspend_device - Save state of one device.
+ *	@dev:	Device.
+ *	@state:	Power state device is entering.
+ */
+
+int suspend_device(struct device * dev, pm_message_t state)
+{
+	int error = 0;
+
+	dev_dbg(dev, "suspending\n");
+
+	dev->power.prev_state = dev->power.power_state;
+
+	if (dev->bus && dev->bus->suspend && !dev->power.power_state)
+		error = dev->bus->suspend(dev, state);
+
+	return error;
+}
+
+
+/**
+ *	device_suspend - Save state and stop all devices in system.
+ *	@state:		Power state to put each device in.
+ *
+ *	Walk the dpm_active list, call ->suspend() for each device, and move
+ *	it to dpm_off.
+ *	Check the return value for each. If it returns 0, then we move the
+ *	the device to the dpm_off list. If it returns -EAGAIN, we move it to
+ *	the dpm_off_irq list. If we get a different error, try and back out.
+ *
+ *	If we hit a failure with any of the devices, call device_resume()
+ *	above to bring the suspended devices back to life.
+ *
+ */
+
+int device_suspend(pm_message_t state)
+{
+	int error = 0;
+
+	down(&dpm_sem);
+	down(&dpm_list_sem);
+	while (!list_empty(&dpm_active) && error == 0) {
+		struct list_head * entry = dpm_active.prev;
+		struct device * dev = to_device(entry);
+
+		get_device(dev);
+		up(&dpm_list_sem);
+
+		error = suspend_device(dev, state);
+
+		down(&dpm_list_sem);
+
+		/* Check if the device got removed */
+		if (!list_empty(&dev->power.entry)) {
+			/* Move it to the dpm_off or dpm_off_irq list */
+			if (!error) {
+				list_del(&dev->power.entry);
+				list_add(&dev->power.entry, &dpm_off);
+			} else if (error == -EAGAIN) {
+				list_del(&dev->power.entry);
+				list_add(&dev->power.entry, &dpm_off_irq);
+				error = 0;
+			}
+		}
+		if (error)
+			printk(KERN_ERR "Could not suspend device %s: "
+				"error %d\n", kobject_name(&dev->kobj), error);
+		put_device(dev);
+	}
+	up(&dpm_list_sem);
+	if (error)
+		dpm_resume();
+	up(&dpm_sem);
+	return error;
+}
+
+EXPORT_SYMBOL_GPL(device_suspend);
+
+
+/**
+ *	device_power_down - Shut down special devices.
+ *	@state:		Power state to enter.
+ *
+ *	Walk the dpm_off_irq list, calling ->power_down() for each device that
+ *	couldn't power down the device with interrupts enabled. When we're
+ *	done, power down system devices.
+ */
+
+int device_power_down(pm_message_t state)
+{
+	int error = 0;
+	struct device * dev;
+
+	list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) {
+		if ((error = suspend_device(dev, state)))
+			break;
+	}
+	if (error)
+		goto Error;
+	if ((error = sysdev_suspend(state)))
+		goto Error;
+ Done:
+	return error;
+ Error:
+	printk(KERN_ERR "Could not power down device %s: "
+		"error %d\n", kobject_name(&dev->kobj), error);
+	dpm_power_up();
+	goto Done;
+}
+
+EXPORT_SYMBOL_GPL(device_power_down);
+