From: Thomas Renninger <trenn@suse.de>
Subject: Introduce acpi_root_table=rsdt boot param and dmi list to force rsdt
Patch-mainline: not yet
References: http://bugzilla.kernel.org/show_bug.cgi?id=8246

This one is part of a patch series:
acpi_thinkpad_introduce_acpi_root_table_boot_param.patch
acpi_thinkpad_introduce_acpica_rsdt_global_variable.patch
acpi_thinkpad_remove_R40e_c-state_blacklist.patch

Blacklist R40e, R51e and T40, T40p, T41, T41p, T42, T42p, R50 and R50p
ThinkPads to use the RSDT instead of the XSDT.

Update: Jan 12 2009 jeffm
* 2.6.29-rc1 introduced acpi_rsdt_forced. I've updated the patch to issue
  a warning that acpi=rsdt is the prefered method of forcing.
* Moved the dmi table stuff to the main dmi table in x86/kernel/acpi/boot.

Update: Apr 10 2009 jeffm
* Removed documentation, since it's deprecated.

Signed-off-by: Thomas Renninger <trenn@suse.de>
Tested-by: Mark Doughty <me@markdoughty.co.uk>
CC: Yakui Zhao <yakui.zhao@intel.com>

---
 arch/x86/kernel/acpi/boot.c |   53 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/tables.c       |    3 ++
 2 files changed, 56 insertions(+)

--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1350,6 +1350,21 @@ static int __init dmi_ignore_irq0_timer_
 	return 0;
 }
 
+static int __init force_acpi_rsdt(const struct dmi_system_id *d)
+{
+	if (!acpi_force) {
+		printk(KERN_NOTICE "%s detected: force use of acpi=rsdt\n",
+		       d->ident);
+		acpi_rsdt_forced = 1;
+	} else {
+		printk(KERN_NOTICE
+		       "Warning: acpi=force overrules DMI blacklist: "
+		       "acpi=rsdt\n");
+	}
+	return 0;
+
+}
+
 /*
  * If your system is blacklisted here, but you find that acpi=force
  * works for you, please contact linux-acpi@vger.kernel.org
@@ -1425,6 +1440,32 @@ static struct dmi_system_id __initdata a
 		     DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
 		     },
 	 },
+
+	/*
+	 * Boxes that need RSDT as ACPI root table
+	 */
+	{
+	    .callback = force_acpi_rsdt,
+	    .ident = "ThinkPad ", /* R40e, broken C-states */
+	    .matches = {
+		DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
+		DMI_MATCH(DMI_BIOS_VERSION, "1SET")},
+	},
+	{
+	    .callback = force_acpi_rsdt,
+	    .ident = "ThinkPad ", /* R50e, slow booting */
+	    .matches = {
+		DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
+		DMI_MATCH(DMI_BIOS_VERSION, "1WET")},
+	},
+	{
+	    .callback = force_acpi_rsdt,
+	    .ident = "ThinkPad ", /* T40, T40p, T41, T41p, T42, T42p
+				     R50, R50p */
+	    .matches = {
+		DMI_MATCH(DMI_BIOS_VENDOR, "IBM"),
+		DMI_MATCH(DMI_BIOS_VERSION, "1RET")},
+	},
 	{}
 };
 
@@ -1612,6 +1653,18 @@ static int __init parse_acpi(char *arg)
 }
 early_param("acpi", parse_acpi);
 
+/* Alias for acpi=rsdt for compatibility with openSUSE 11.1 and SLE11 */
+static int __init parse_acpi_root_table(char *opt)
+{
+	if (!strcmp(opt, "rsdt")) {
+		acpi_rsdt_forced = 1;
+		printk(KERN_WARNING "acpi_root_table=rsdt is deprecated. "
+		       "Please use acpi=rsdt instead.\n");
+	}
+	return 0;
+}
+early_param("acpi_root_table", parse_acpi_root_table);
+
 /* FIXME: Using pci= for an ACPI parameter is a travesty. */
 static int __init parse_pci(char *arg)
 {
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -339,6 +339,9 @@ int __init acpi_table_init(void)
 {
 	acpi_status status;
 
+	if (acpi_rsdt_forced)
+		printk(KERN_INFO "Using RSDT as ACPI root table\n");
+
 	status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
 	if (ACPI_FAILURE(status))
 		return 1;
