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/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
new file mode 100644
index 0000000..0a5d2a9
--- /dev/null
+++ b/drivers/acpi/sleep/main.c
@@ -0,0 +1,234 @@
+/*
+ * sleep.c - ACPI sleep support.
+ *
+ * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
+ * Copyright (c) 2000-2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Lab
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dmi.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <asm/io.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include "sleep.h"
+
+u8 sleep_states[ACPI_S_STATE_COUNT];
+
+static struct pm_ops acpi_pm_ops;
+
+extern void do_suspend_lowlevel_s4bios(void);
+extern void do_suspend_lowlevel(void);
+
+static u32 acpi_suspend_states[] = {
+	[PM_SUSPEND_ON]		= ACPI_STATE_S0,
+	[PM_SUSPEND_STANDBY]	= ACPI_STATE_S1,
+	[PM_SUSPEND_MEM]	= ACPI_STATE_S3,
+	[PM_SUSPEND_DISK]	= ACPI_STATE_S4,
+};
+
+static int init_8259A_after_S1;
+
+/**
+ *	acpi_pm_prepare - Do preliminary suspend work.
+ *	@pm_state:		suspend state we're entering.
+ *
+ *	Make sure we support the state. If we do, and we need it, set the
+ *	firmware waking vector and do arch-specific nastiness to get the 
+ *	wakeup code to the waking vector. 
+ */
+
+static int acpi_pm_prepare(suspend_state_t pm_state)
+{
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	if (!sleep_states[acpi_state])
+		return -EPERM;
+
+	/* do we have a wakeup address for S2 and S3? */
+	/* Here, we support only S4BIOS, those we set the wakeup address */
+	/* S4OS is only supported for now via swsusp.. */
+	if (pm_state == PM_SUSPEND_MEM || pm_state == PM_SUSPEND_DISK) {
+		if (!acpi_wakeup_address)
+			return -EFAULT;
+		acpi_set_firmware_waking_vector(
+			(acpi_physical_address) virt_to_phys(
+				(void *)acpi_wakeup_address));
+	}
+	ACPI_FLUSH_CPU_CACHE();
+	acpi_enable_wakeup_device_prep(acpi_state);
+	acpi_enter_sleep_state_prep(acpi_state);
+	return 0;
+}
+
+
+/**
+ *	acpi_pm_enter - Actually enter a sleep state.
+ *	@pm_state:		State we're entering.
+ *
+ *	Flush caches and go to sleep. For STR or STD, we have to call 
+ *	arch-specific assembly, which in turn call acpi_enter_sleep_state().
+ *	It's unfortunate, but it works. Please fix if you're feeling frisky.
+ */
+
+static int acpi_pm_enter(suspend_state_t pm_state)
+{
+	acpi_status status = AE_OK;
+	unsigned long flags = 0;
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	ACPI_FLUSH_CPU_CACHE();
+
+	/* Do arch specific saving of state. */
+	if (pm_state > PM_SUSPEND_STANDBY) {
+		int error = acpi_save_state_mem();
+		if (error)
+			return error;
+	}
+
+
+	local_irq_save(flags);
+	acpi_enable_wakeup_device(acpi_state);
+	switch (pm_state)
+	{
+	case PM_SUSPEND_STANDBY:
+		barrier();
+		status = acpi_enter_sleep_state(acpi_state);
+		break;
+
+	case PM_SUSPEND_MEM:
+		do_suspend_lowlevel();
+		break;
+
+	case PM_SUSPEND_DISK:
+		if (acpi_pm_ops.pm_disk_mode == PM_DISK_PLATFORM)
+			status = acpi_enter_sleep_state(acpi_state);
+		else
+			do_suspend_lowlevel_s4bios();
+		break;
+	default:
+		return -EINVAL;
+	}
+	local_irq_restore(flags);
+	printk(KERN_DEBUG "Back to C!\n");
+
+	/* restore processor state
+	 * We should only be here if we're coming back from STR or STD.
+	 * And, in the case of the latter, the memory image should have already
+	 * been loaded from disk.
+	 */
+	if (pm_state > PM_SUSPEND_STANDBY)
+		acpi_restore_state_mem();
+
+
+	return ACPI_SUCCESS(status) ? 0 : -EFAULT;
+}
+
+
+/**
+ *	acpi_pm_finish - Finish up suspend sequence.
+ *	@pm_state:		State we're coming out of.
+ *
+ *	This is called after we wake back up (or if entering the sleep state
+ *	failed). 
+ */
+
+static int acpi_pm_finish(suspend_state_t pm_state)
+{
+	u32 acpi_state = acpi_suspend_states[pm_state];
+
+	acpi_leave_sleep_state(acpi_state);
+	acpi_disable_wakeup_device(acpi_state);
+
+	/* reset firmware waking vector */
+	acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+
+	if (init_8259A_after_S1) {
+		printk("Broken toshiba laptop -> kicking interrupts\n");
+		init_8259A(0);
+	}
+	return 0;
+}
+
+
+int acpi_suspend(u32 acpi_state)
+{
+	suspend_state_t states[] = {
+		[1]	= PM_SUSPEND_STANDBY,
+		[3]	= PM_SUSPEND_MEM,
+		[4]	= PM_SUSPEND_DISK,
+	};
+
+	if (acpi_state <= 4 && states[acpi_state])
+		return pm_suspend(states[acpi_state]);
+	return -EINVAL;
+}
+
+static struct pm_ops acpi_pm_ops = {
+	.prepare	= acpi_pm_prepare,
+	.enter		= acpi_pm_enter,
+	.finish		= acpi_pm_finish,
+};
+
+
+/*
+ * Toshiba fails to preserve interrupts over S1, reinitialization
+ * of 8259 is needed after S1 resume.
+ */
+static int __init init_ints_after_s1(struct dmi_system_id *d)
+{
+	printk(KERN_WARNING "%s with broken S1 detected.\n", d->ident);
+	init_8259A_after_S1 = 1;
+	return 0;
+}
+
+static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
+	{
+		.callback = init_ints_after_s1,
+		.ident = "Toshiba Satellite 4030cdt",
+		.matches = { DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), },
+	},
+	{ },
+};
+
+static int __init acpi_sleep_init(void)
+{
+	int			i = 0;
+
+	dmi_check_system(acpisleep_dmi_table);
+
+	if (acpi_disabled)
+		return 0;
+
+	printk(KERN_INFO PREFIX "(supports");
+	for (i=0; i < ACPI_S_STATE_COUNT; i++) {
+		acpi_status status;
+		u8 type_a, type_b;
+		status = acpi_get_sleep_type_data(i, &type_a, &type_b);
+		if (ACPI_SUCCESS(status)) {
+			sleep_states[i] = 1;
+			printk(" S%d", i);
+		}
+		if (i == ACPI_STATE_S4) {
+			if (acpi_gbl_FACS->S4bios_f) {
+				sleep_states[i] = 1;
+				printk(" S4bios");
+				acpi_pm_ops.pm_disk_mode = PM_DISK_FIRMWARE;
+			}
+			if (sleep_states[i])
+				acpi_pm_ops.pm_disk_mode = PM_DISK_PLATFORM;
+		}
+	}
+	printk(")\n");
+
+	pm_set_ops(&acpi_pm_ops);
+	return 0;
+}
+
+late_initcall(acpi_sleep_init);