summary refs log tree commit diff
path: root/drivers/input/serio
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-04-16 08:51:52 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-04-16 08:51:52 -0700
commit0c387ec88abf4f1ddfe8c3be10ea981bc447b406 (patch)
tree7510842a16aa54e3fec96aed2b3126109cda8d85 /drivers/input/serio
parentba28f22e7cf16cb310bb491cbb3f7d0d5d1f5c5d (diff)
parent3f3e7c6e139f704e2f48ea3b45ff7724a8d46456 (diff)
downloadlinux-0c387ec88abf4f1ddfe8c3be10ea981bc447b406.tar.gz
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h28
-rw-r--r--drivers/input/serio/i8042.c37
2 files changed, 57 insertions, 8 deletions
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 83ed2d56b924..fb8a3cd3ffd0 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -377,6 +377,24 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
 	{ }
 };
 
+static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
+	{
+		.ident = "MSI Wind U-100",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+		},
+	},
+	{
+		.ident = "LG Electronics X110",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "X110"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "LG Electronics Inc."),
+		},
+	},
+	{ }
+};
+
 #ifdef CONFIG_PNP
 static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 	{
@@ -386,6 +404,13 @@ static struct dmi_system_id __initdata i8042_dmi_nopnp_table[] = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
 		},
 	},
+	{
+		.ident = "MSI Wind U-100",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "U-100"),
+			DMI_MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+		},
+	},
 	{ }
 };
 #endif
@@ -698,6 +723,9 @@ static int __init i8042_platform_init(void)
 #endif
 
 #ifdef CONFIG_X86
+	if (dmi_check_system(i8042_dmi_reset_table))
+		i8042_reset = 1;
+
 	if (dmi_check_system(i8042_dmi_noloop_table))
 		i8042_noloop = 1;
 
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 170f71ee5772..3cffb704e374 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -712,22 +712,43 @@ static int i8042_controller_check(void)
 static int i8042_controller_selftest(void)
 {
 	unsigned char param;
+	int i = 0;
 
 	if (!i8042_reset)
 		return 0;
 
-	if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
-		printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
-		return -ENODEV;
-	}
+	/*
+	 * We try this 5 times; on some really fragile systems this does not
+	 * take the first time...
+	 */
+	do {
+
+		if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
+			printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n");
+			return -ENODEV;
+		}
+
+		if (param == I8042_RET_CTL_TEST)
+			return 0;
 
-	if (param != I8042_RET_CTL_TEST) {
 		printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n",
-			 param, I8042_RET_CTL_TEST);
-		return -EIO;
-	}
+			param, I8042_RET_CTL_TEST);
+		msleep(50);
+	} while (i++ < 5);
 
+#ifdef CONFIG_X86
+	/*
+	 * On x86, we don't fail entire i8042 initialization if controller
+	 * reset fails in hopes that keyboard port will still be functional
+	 * and user will still get a working keyboard. This is especially
+	 * important on netbooks. On other arches we trust hardware more.
+	 */
+	printk(KERN_INFO
+		"i8042: giving up on controller selftest, continuing anyway...\n");
 	return 0;
+#else
+	return -EIO;
+#endif
 }
 
 /*