aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/ec.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f70796081c4c..3fcb9132881e 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -119,6 +119,7 @@ static struct acpi_ec {
119} *boot_ec, *first_ec; 119} *boot_ec, *first_ec;
120 120
121static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ 121static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
122static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
122 123
123/* -------------------------------------------------------------------------- 124/* --------------------------------------------------------------------------
124 Transaction Management 125 Transaction Management
@@ -899,6 +900,33 @@ static const struct acpi_device_id ec_device_ids[] = {
899 {"", 0}, 900 {"", 0},
900}; 901};
901 902
903/* ASUStek often supplies us with broken ECDT, validate it */
904static int ec_validate_ecdt(const struct dmi_system_id *id)
905{
906 EC_FLAGS_VALIDATE_ECDT = 1;
907 return 0;
908}
909
910/* MSI EC needs special treatment, enable it */
911static int ec_flag_msi(const struct dmi_system_id *id)
912{
913 EC_FLAGS_MSI = 1;
914 EC_FLAGS_VALIDATE_ECDT = 1;
915 return 0;
916}
917
918static struct dmi_system_id __initdata ec_dmi_table[] = {
919 {
920 ec_flag_msi, "MSI hardware", {
921 DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
922 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
923 {
924 ec_validate_ecdt, "ASUS hardware", {
925 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
926 {},
927};
928
929
902int __init acpi_ec_ecdt_probe(void) 930int __init acpi_ec_ecdt_probe(void)
903{ 931{
904 acpi_status status; 932 acpi_status status;
@@ -911,11 +939,7 @@ int __init acpi_ec_ecdt_probe(void)
911 /* 939 /*
912 * Generate a boot ec context 940 * Generate a boot ec context
913 */ 941 */
914 if (dmi_name_in_vendors("Micro-Star") || 942 dmi_check_system(ec_dmi_table);
915 dmi_name_in_vendors("Notebook")) {
916 pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
917 EC_FLAGS_MSI = 1;
918 }
919 status = acpi_get_table(ACPI_SIG_ECDT, 1, 943 status = acpi_get_table(ACPI_SIG_ECDT, 1,
920 (struct acpi_table_header **)&ecdt_ptr); 944 (struct acpi_table_header **)&ecdt_ptr);
921 if (ACPI_SUCCESS(status)) { 945 if (ACPI_SUCCESS(status)) {
@@ -926,7 +950,7 @@ int __init acpi_ec_ecdt_probe(void)
926 boot_ec->handle = ACPI_ROOT_OBJECT; 950 boot_ec->handle = ACPI_ROOT_OBJECT;
927 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); 951 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
928 /* Don't trust ECDT, which comes from ASUSTek */ 952 /* Don't trust ECDT, which comes from ASUSTek */
929 if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) 953 if (!EC_FLAGS_VALIDATE_ECDT)
930 goto install; 954 goto install;
931 saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); 955 saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
932 if (!saved_ec) 956 if (!saved_ec)
@@ -934,6 +958,7 @@ int __init acpi_ec_ecdt_probe(void)
934 memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); 958 memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
935 /* fall through */ 959 /* fall through */
936 } 960 }
961
937 /* This workaround is needed only on some broken machines, 962 /* This workaround is needed only on some broken machines,
938 * which require early EC, but fail to provide ECDT */ 963 * which require early EC, but fail to provide ECDT */
939 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); 964 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");