xref: /openbmc/linux/drivers/acpi/blacklist.c (revision 160b8e75)
1 /*
2  *  blacklist.c
3  *
4  *  Check to see if the given machine has a known bad ACPI BIOS
5  *  or if the BIOS is too old.
6  *  Check given machine against acpi_rev_dmi_table[].
7  *
8  *  Copyright (C) 2004 Len Brown <len.brown@intel.com>
9  *  Copyright (C) 2002 Andy Grover <andrew.grover@intel.com>
10  *
11  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or (at
16  *  your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful, but
19  *  WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21  *  General Public License for more details.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  */
25 
26 #include <linux/kernel.h>
27 #include <linux/init.h>
28 #include <linux/acpi.h>
29 #include <linux/dmi.h>
30 
31 #include "internal.h"
32 
33 static const struct dmi_system_id acpi_rev_dmi_table[] __initconst;
34 
35 /*
36  * POLICY: If *anything* doesn't work, put it on the blacklist.
37  *	   If they are critical errors, mark it critical, and abort driver load.
38  */
39 static struct acpi_platform_list acpi_blacklist[] __initdata = {
40 	/* Compaq Presario 1700 */
41 	{"PTLTD ", "  DSDT  ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
42 	 "Multiple problems", 1},
43 	/* Sony FX120, FX140, FX150? */
44 	{"SONY  ", "U0      ", 0x20010313, ACPI_SIG_DSDT, less_than_or_equal,
45 	 "ACPI driver problem", 1},
46 	/* Compaq Presario 800, Insyde BIOS */
47 	{"INT440", "SYSFexxx", 0x00001001, ACPI_SIG_DSDT, less_than_or_equal,
48 	 "Does not use _REG to protect EC OpRegions", 1},
49 	/* IBM 600E - _ADR should return 7, but it returns 1 */
50 	{"IBM   ", "TP600E  ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
51 	 "Incorrect _ADR", 1},
52 
53 	{ }
54 };
55 
56 int __init acpi_blacklisted(void)
57 {
58 	int i;
59 	int blacklisted = 0;
60 
61 	i = acpi_match_platform_list(acpi_blacklist);
62 	if (i >= 0) {
63 		pr_err(PREFIX "Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n",
64 		       acpi_blacklist[i].oem_id,
65 		       acpi_blacklist[i].oem_table_id,
66 		       acpi_blacklist[i].oem_revision);
67 
68 		pr_err(PREFIX "Reason: %s. This is a %s error\n",
69 		       acpi_blacklist[i].reason,
70 		       (acpi_blacklist[i].data ?
71 			"non-recoverable" : "recoverable"));
72 
73 		blacklisted = acpi_blacklist[i].data;
74 	}
75 
76 	(void)early_acpi_osi_init();
77 	dmi_check_system(acpi_rev_dmi_table);
78 
79 	return blacklisted;
80 }
81 #ifdef CONFIG_DMI
82 #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
83 static int __init dmi_enable_rev_override(const struct dmi_system_id *d)
84 {
85 	printk(KERN_NOTICE PREFIX "DMI detected: %s (force ACPI _REV to 5)\n",
86 	       d->ident);
87 	acpi_rev_override_setup(NULL);
88 	return 0;
89 }
90 #endif
91 
92 static const struct dmi_system_id acpi_rev_dmi_table[] __initconst = {
93 #ifdef CONFIG_ACPI_REV_OVERRIDE_POSSIBLE
94 	/*
95 	 * DELL XPS 13 (2015) switches sound between HDA and I2S
96 	 * depending on the ACPI _REV callback. If userspace supports
97 	 * I2S sufficiently (or if you do not care about sound), you
98 	 * can safely disable this quirk.
99 	 */
100 	{
101 	 .callback = dmi_enable_rev_override,
102 	 .ident = "DELL XPS 13 (2015)",
103 	 .matches = {
104 		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
105 		      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
106 		},
107 	},
108 	{
109 	 .callback = dmi_enable_rev_override,
110 	 .ident = "DELL Precision 5520",
111 	 .matches = {
112 		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
113 		      DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"),
114 		},
115 	},
116 	{
117 	 .callback = dmi_enable_rev_override,
118 	 .ident = "DELL Precision 3520",
119 	 .matches = {
120 		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
121 		      DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"),
122 		},
123 	},
124 	/*
125 	 * Resolves a quirk with the Dell Latitude 3350 that
126 	 * causes the ethernet adapter to not function.
127 	 */
128 	{
129 	 .callback = dmi_enable_rev_override,
130 	 .ident = "DELL Latitude 3350",
131 	 .matches = {
132 		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
133 		      DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
134 		},
135 	},
136 	{
137 	 .callback = dmi_enable_rev_override,
138 	 .ident = "DELL Inspiron 7537",
139 	 .matches = {
140 		      DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
141 		      DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7537"),
142 		},
143 	},
144 #endif
145 	{}
146 };
147 
148 #endif /* CONFIG_DMI */
149