Skip to content

Commit 5aa5911

Browse files
toshikanirafaeljw
authored andcommitted
ACPI / blacklist: add acpi_match_platform_list()
ACPI OEM ID / OEM Table ID / Revision can be used to identify a platform based on ACPI firmware info. acpi_blacklisted(), intel_pstate_platform_pwr_mgmt_exists(), and some other funcs, have been using similar check to detect a list of platforms that require special handlings. Move the platform check in acpi_blacklisted() to a new common utility function, acpi_match_platform_list(), so that other drivers do not have to implement their own version. There is no change in functionality. Signed-off-by: Toshi Kani <[email protected]> Reviewed-by: Borislav Petkov <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent cc4a41f commit 5aa5911

File tree

3 files changed

+69
-69
lines changed

3 files changed

+69
-69
lines changed

drivers/acpi/blacklist.c

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,13 @@
3030

3131
#include "internal.h"
3232

33-
enum acpi_blacklist_predicates {
34-
all_versions,
35-
less_than_or_equal,
36-
equal,
37-
greater_than_or_equal,
38-
};
39-
40-
struct acpi_blacklist_item {
41-
char oem_id[7];
42-
char oem_table_id[9];
43-
u32 oem_revision;
44-
char *table;
45-
enum acpi_blacklist_predicates oem_revision_predicate;
46-
char *reason;
47-
u32 is_critical_error;
48-
};
49-
5033
static struct dmi_system_id acpi_rev_dmi_table[] __initdata;
5134

5235
/*
5336
* POLICY: If *anything* doesn't work, put it on the blacklist.
5437
* If they are critical errors, mark it critical, and abort driver load.
5538
*/
56-
static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
39+
static struct acpi_platform_list acpi_blacklist[] __initdata = {
5740
/* Compaq Presario 1700 */
5841
{"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal,
5942
"Multiple problems", 1},
@@ -67,65 +50,27 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
6750
{"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
6851
"Incorrect _ADR", 1},
6952

70-
{""}
53+
{ }
7154
};
7255

7356
int __init acpi_blacklisted(void)
7457
{
75-
int i = 0;
58+
int i;
7659
int blacklisted = 0;
77-
struct acpi_table_header table_header;
78-
79-
while (acpi_blacklist[i].oem_id[0] != '\0') {
80-
if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
81-
i++;
82-
continue;
83-
}
84-
85-
if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
86-
i++;
87-
continue;
88-
}
89-
90-
if (strncmp
91-
(acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
92-
8)) {
93-
i++;
94-
continue;
95-
}
96-
97-
if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
98-
|| (acpi_blacklist[i].oem_revision_predicate ==
99-
less_than_or_equal
100-
&& table_header.oem_revision <=
101-
acpi_blacklist[i].oem_revision)
102-
|| (acpi_blacklist[i].oem_revision_predicate ==
103-
greater_than_or_equal
104-
&& table_header.oem_revision >=
105-
acpi_blacklist[i].oem_revision)
106-
|| (acpi_blacklist[i].oem_revision_predicate == equal
107-
&& table_header.oem_revision ==
108-
acpi_blacklist[i].oem_revision)) {
10960

110-
printk(KERN_ERR PREFIX
111-
"Vendor \"%6.6s\" System \"%8.8s\" "
112-
"Revision 0x%x has a known ACPI BIOS problem.\n",
113-
acpi_blacklist[i].oem_id,
114-
acpi_blacklist[i].oem_table_id,
115-
acpi_blacklist[i].oem_revision);
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);
11667

117-
printk(KERN_ERR PREFIX
118-
"Reason: %s. This is a %s error\n",
119-
acpi_blacklist[i].reason,
120-
(acpi_blacklist[i].
121-
is_critical_error ? "non-recoverable" :
122-
"recoverable"));
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"));
12372

124-
blacklisted = acpi_blacklist[i].is_critical_error;
125-
break;
126-
} else {
127-
i++;
128-
}
73+
blacklisted = acpi_blacklist[i].data;
12974
}
13075

13176
(void)early_acpi_osi_init();

drivers/acpi/utils.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,3 +816,39 @@ static int __init acpi_backlight(char *str)
816816
return 1;
817817
}
818818
__setup("acpi_backlight=", acpi_backlight);
819+
820+
/**
821+
* acpi_match_platform_list - Check if the system matches with a given list
822+
* @plat: pointer to acpi_platform_list table terminated by a NULL entry
823+
*
824+
* Return the matched index if the system is found in the platform list.
825+
* Otherwise, return a negative error code.
826+
*/
827+
int acpi_match_platform_list(const struct acpi_platform_list *plat)
828+
{
829+
struct acpi_table_header hdr;
830+
int idx = 0;
831+
832+
if (acpi_disabled)
833+
return -ENODEV;
834+
835+
for (; plat->oem_id[0]; plat++, idx++) {
836+
if (ACPI_FAILURE(acpi_get_table_header(plat->table, 0, &hdr)))
837+
continue;
838+
839+
if (strncmp(plat->oem_id, hdr.oem_id, ACPI_OEM_ID_SIZE))
840+
continue;
841+
842+
if (strncmp(plat->oem_table_id, hdr.oem_table_id, ACPI_OEM_TABLE_ID_SIZE))
843+
continue;
844+
845+
if ((plat->pred == all_versions) ||
846+
(plat->pred == less_than_or_equal && hdr.oem_revision <= plat->oem_revision) ||
847+
(plat->pred == greater_than_or_equal && hdr.oem_revision >= plat->oem_revision) ||
848+
(plat->pred == equal && hdr.oem_revision == plat->oem_revision))
849+
return idx;
850+
}
851+
852+
return -ENODEV;
853+
}
854+
EXPORT_SYMBOL(acpi_match_platform_list);

include/linux/acpi.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,25 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
556556
#define ACPI_OST_SC_DRIVER_LOAD_FAILURE 0x81
557557
#define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82
558558

559+
enum acpi_predicate {
560+
all_versions,
561+
less_than_or_equal,
562+
equal,
563+
greater_than_or_equal,
564+
};
565+
566+
/* Table must be terminted by a NULL entry */
567+
struct acpi_platform_list {
568+
char oem_id[ACPI_OEM_ID_SIZE+1];
569+
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE+1];
570+
u32 oem_revision;
571+
char *table;
572+
enum acpi_predicate pred;
573+
char *reason;
574+
u32 data;
575+
};
576+
int acpi_match_platform_list(const struct acpi_platform_list *plat);
577+
559578
extern void acpi_early_init(void);
560579
extern void acpi_subsystem_init(void);
561580

0 commit comments

Comments
 (0)