diff options
-rw-r--r-- | drivers/acpi/ec.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8a4897d3899d..baef28c1e630 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -119,6 +119,8 @@ static struct acpi_ec { | |||
119 | } *boot_ec, *first_ec; | 119 | } *boot_ec, *first_ec; |
120 | 120 | ||
121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ | 121 | static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ |
122 | static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */ | ||
123 | static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ | ||
122 | 124 | ||
123 | /* -------------------------------------------------------------------------- | 125 | /* -------------------------------------------------------------------------- |
124 | Transaction Management | 126 | Transaction Management |
@@ -897,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = { | |||
897 | {"", 0}, | 899 | {"", 0}, |
898 | }; | 900 | }; |
899 | 901 | ||
902 | /* Some BIOS do not survive early DSDT scan, skip it */ | ||
903 | static int ec_skip_dsdt_scan(const struct dmi_system_id *id) | ||
904 | { | ||
905 | EC_FLAGS_SKIP_DSDT_SCAN = 1; | ||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | /* ASUStek often supplies us with broken ECDT, validate it */ | ||
910 | static int ec_validate_ecdt(const struct dmi_system_id *id) | ||
911 | { | ||
912 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | /* MSI EC needs special treatment, enable it */ | ||
917 | static int ec_flag_msi(const struct dmi_system_id *id) | ||
918 | { | ||
919 | EC_FLAGS_MSI = 1; | ||
920 | EC_FLAGS_VALIDATE_ECDT = 1; | ||
921 | return 0; | ||
922 | } | ||
923 | |||
924 | static struct dmi_system_id __initdata ec_dmi_table[] = { | ||
925 | { | ||
926 | ec_skip_dsdt_scan, "Compal JFL92", { | ||
927 | DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"), | ||
928 | DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL}, | ||
929 | { | ||
930 | ec_flag_msi, "MSI hardware", { | ||
931 | DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"), | ||
932 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL}, | ||
933 | { | ||
934 | ec_validate_ecdt, "ASUS hardware", { | ||
935 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | ||
936 | {}, | ||
937 | }; | ||
938 | |||
939 | |||
900 | int __init acpi_ec_ecdt_probe(void) | 940 | int __init acpi_ec_ecdt_probe(void) |
901 | { | 941 | { |
902 | acpi_status status; | 942 | acpi_status status; |
@@ -909,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
909 | /* | 949 | /* |
910 | * Generate a boot ec context | 950 | * Generate a boot ec context |
911 | */ | 951 | */ |
912 | if (dmi_name_in_vendors("Micro-Star") || | 952 | dmi_check_system(ec_dmi_table); |
913 | dmi_name_in_vendors("Notebook")) { | ||
914 | pr_info(PREFIX "Enabling special treatment for EC from MSI.\n"); | ||
915 | EC_FLAGS_MSI = 1; | ||
916 | } | ||
917 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 953 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
918 | (struct acpi_table_header **)&ecdt_ptr); | 954 | (struct acpi_table_header **)&ecdt_ptr); |
919 | if (ACPI_SUCCESS(status)) { | 955 | if (ACPI_SUCCESS(status)) { |
@@ -924,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void) | |||
924 | boot_ec->handle = ACPI_ROOT_OBJECT; | 960 | boot_ec->handle = ACPI_ROOT_OBJECT; |
925 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); | 961 | acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); |
926 | /* Don't trust ECDT, which comes from ASUSTek */ | 962 | /* Don't trust ECDT, which comes from ASUSTek */ |
927 | if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) | 963 | if (!EC_FLAGS_VALIDATE_ECDT) |
928 | goto install; | 964 | goto install; |
929 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); | 965 | saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); |
930 | if (!saved_ec) | 966 | if (!saved_ec) |
@@ -932,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void) | |||
932 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); | 968 | memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); |
933 | /* fall through */ | 969 | /* fall through */ |
934 | } | 970 | } |
971 | |||
972 | if (EC_FLAGS_SKIP_DSDT_SCAN) | ||
973 | return -ENODEV; | ||
974 | |||
935 | /* This workaround is needed only on some broken machines, | 975 | /* This workaround is needed only on some broken machines, |
936 | * which require early EC, but fail to provide ECDT */ | 976 | * which require early EC, but fail to provide ECDT */ |
937 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 977 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |