Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <toshi.kani@hpe.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Toshi Kani and committed by
Rafael J. Wysocki
5aa5911a cc4a41fe

+69 -69
+14 -69
drivers/acpi/blacklist.c
··· 30 30 31 31 #include "internal.h" 32 32 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 - 50 33 static struct dmi_system_id acpi_rev_dmi_table[] __initdata; 51 34 52 35 /* 53 36 * POLICY: If *anything* doesn't work, put it on the blacklist. 54 37 * If they are critical errors, mark it critical, and abort driver load. 55 38 */ 56 - static struct acpi_blacklist_item acpi_blacklist[] __initdata = { 39 + static struct acpi_platform_list acpi_blacklist[] __initdata = { 57 40 /* Compaq Presario 1700 */ 58 41 {"PTLTD ", " DSDT ", 0x06040000, ACPI_SIG_DSDT, less_than_or_equal, 59 42 "Multiple problems", 1}, ··· 50 67 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, 51 68 "Incorrect _ADR", 1}, 52 69 53 - {""} 70 + { } 54 71 }; 55 72 56 73 int __init acpi_blacklisted(void) 57 74 { 58 - int i = 0; 75 + int i; 59 76 int blacklisted = 0; 60 - struct acpi_table_header table_header; 61 77 62 - while (acpi_blacklist[i].oem_id[0] != '\0') { 63 - if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { 64 - i++; 65 - continue; 66 - } 78 + i = acpi_match_platform_list(acpi_blacklist); 79 + if (i >= 0) { 80 + pr_err(PREFIX "Vendor \"%6.6s\" System \"%8.8s\" Revision 0x%x has a known ACPI BIOS problem.\n", 81 + acpi_blacklist[i].oem_id, 82 + acpi_blacklist[i].oem_table_id, 83 + acpi_blacklist[i].oem_revision); 67 84 68 - if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) { 69 - i++; 70 - continue; 71 - } 85 + pr_err(PREFIX "Reason: %s. This is a %s error\n", 86 + acpi_blacklist[i].reason, 87 + (acpi_blacklist[i].data ? 88 + "non-recoverable" : "recoverable")); 72 89 73 - if (strncmp 74 - (acpi_blacklist[i].oem_table_id, table_header.oem_table_id, 75 - 8)) { 76 - i++; 77 - continue; 78 - } 79 - 80 - if ((acpi_blacklist[i].oem_revision_predicate == all_versions) 81 - || (acpi_blacklist[i].oem_revision_predicate == 82 - less_than_or_equal 83 - && table_header.oem_revision <= 84 - acpi_blacklist[i].oem_revision) 85 - || (acpi_blacklist[i].oem_revision_predicate == 86 - greater_than_or_equal 87 - && table_header.oem_revision >= 88 - acpi_blacklist[i].oem_revision) 89 - || (acpi_blacklist[i].oem_revision_predicate == equal 90 - && table_header.oem_revision == 91 - acpi_blacklist[i].oem_revision)) { 92 - 93 - printk(KERN_ERR PREFIX 94 - "Vendor \"%6.6s\" System \"%8.8s\" " 95 - "Revision 0x%x has a known ACPI BIOS problem.\n", 96 - acpi_blacklist[i].oem_id, 97 - acpi_blacklist[i].oem_table_id, 98 - acpi_blacklist[i].oem_revision); 99 - 100 - printk(KERN_ERR PREFIX 101 - "Reason: %s. This is a %s error\n", 102 - acpi_blacklist[i].reason, 103 - (acpi_blacklist[i]. 104 - is_critical_error ? "non-recoverable" : 105 - "recoverable")); 106 - 107 - blacklisted = acpi_blacklist[i].is_critical_error; 108 - break; 109 - } else { 110 - i++; 111 - } 90 + blacklisted = acpi_blacklist[i].data; 112 91 } 113 92 114 93 (void)early_acpi_osi_init();
+36
drivers/acpi/utils.c
··· 816 816 return 1; 817 817 } 818 818 __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);
+19
include/linux/acpi.h
··· 556 556 #define ACPI_OST_SC_DRIVER_LOAD_FAILURE 0x81 557 557 #define ACPI_OST_SC_INSERT_NOT_SUPPORTED 0x82 558 558 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 + 559 578 extern void acpi_early_init(void); 560 579 extern void acpi_subsystem_init(void); 561 580