diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 113 |
1 files changed, 77 insertions, 36 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1b..055d7b701fff 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -110,9 +110,6 @@ struct acpi_ioremap { | |||
110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); |
112 | 112 | ||
113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
115 | |||
116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
117 | 114 | ||
118 | /* | 115 | /* |
@@ -152,8 +149,7 @@ static struct osi_linux { | |||
152 | unsigned int enable:1; | 149 | unsigned int enable:1; |
153 | unsigned int dmi:1; | 150 | unsigned int dmi:1; |
154 | unsigned int cmdline:1; | 151 | unsigned int cmdline:1; |
155 | unsigned int known:1; | 152 | } osi_linux = {0, 0, 0}; |
156 | } osi_linux = { 0, 0, 0, 0}; | ||
157 | 153 | ||
158 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 154 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
159 | { | 155 | { |
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str) | |||
1055 | 1051 | ||
1056 | __setup("acpi_os_name=", acpi_os_name_setup); | 1052 | __setup("acpi_os_name=", acpi_os_name_setup); |
1057 | 1053 | ||
1054 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
1055 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
1056 | |||
1057 | struct osi_setup_entry { | ||
1058 | char string[OSI_STRING_LENGTH_MAX]; | ||
1059 | bool enable; | ||
1060 | }; | ||
1061 | |||
1062 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
1063 | |||
1064 | void __init acpi_osi_setup(char *str) | ||
1065 | { | ||
1066 | struct osi_setup_entry *osi; | ||
1067 | bool enable = true; | ||
1068 | int i; | ||
1069 | |||
1070 | if (!acpi_gbl_create_osi_method) | ||
1071 | return; | ||
1072 | |||
1073 | if (str == NULL || *str == '\0') { | ||
1074 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
1075 | acpi_gbl_create_osi_method = FALSE; | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | if (*str == '!') { | ||
1080 | str++; | ||
1081 | enable = false; | ||
1082 | } | ||
1083 | |||
1084 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1085 | osi = &osi_setup_entries[i]; | ||
1086 | if (!strcmp(osi->string, str)) { | ||
1087 | osi->enable = enable; | ||
1088 | break; | ||
1089 | } else if (osi->string[0] == '\0') { | ||
1090 | osi->enable = enable; | ||
1091 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1058 | static void __init set_osi_linux(unsigned int enable) | 1097 | static void __init set_osi_linux(unsigned int enable) |
1059 | { | 1098 | { |
1060 | if (osi_linux.enable != enable) { | 1099 | if (osi_linux.enable != enable) |
1061 | osi_linux.enable = enable; | 1100 | osi_linux.enable = enable; |
1062 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
1063 | enable ? "Add": "Delet"); | ||
1064 | } | ||
1065 | 1101 | ||
1066 | if (osi_linux.enable) | 1102 | if (osi_linux.enable) |
1067 | acpi_osi_setup("Linux"); | 1103 | acpi_osi_setup("Linux"); |
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable) | |||
1073 | 1109 | ||
1074 | static void __init acpi_cmdline_osi_linux(unsigned int enable) | 1110 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
1075 | { | 1111 | { |
1076 | osi_linux.cmdline = 1; /* cmdline set the default */ | 1112 | osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ |
1113 | osi_linux.dmi = 0; | ||
1077 | set_osi_linux(enable); | 1114 | set_osi_linux(enable); |
1078 | 1115 | ||
1079 | return; | 1116 | return; |
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) | |||
1081 | 1118 | ||
1082 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | 1119 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) |
1083 | { | 1120 | { |
1084 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
1085 | |||
1086 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 1121 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
1087 | 1122 | ||
1088 | if (enable == -1) | 1123 | if (enable == -1) |
1089 | return; | 1124 | return; |
1090 | 1125 | ||
1091 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | 1126 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ |
1092 | |||
1093 | set_osi_linux(enable); | 1127 | set_osi_linux(enable); |
1094 | 1128 | ||
1095 | return; | 1129 | return; |
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1104 | */ | 1138 | */ |
1105 | static void __init acpi_osi_setup_late(void) | 1139 | static void __init acpi_osi_setup_late(void) |
1106 | { | 1140 | { |
1107 | char *str = osi_setup_string; | 1141 | struct osi_setup_entry *osi; |
1142 | char *str; | ||
1143 | int i; | ||
1144 | acpi_status status; | ||
1108 | 1145 | ||
1109 | if (*str == '\0') | 1146 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1110 | return; | 1147 | osi = &osi_setup_entries[i]; |
1148 | str = osi->string; | ||
1111 | 1149 | ||
1112 | if (!strcmp("!Linux", str)) { | 1150 | if (*str == '\0') |
1113 | acpi_cmdline_osi_linux(0); /* !enable */ | 1151 | break; |
1114 | } else if (*str == '!') { | 1152 | if (osi->enable) { |
1115 | if (acpi_remove_interface(++str) == AE_OK) | 1153 | status = acpi_install_interface(str); |
1116 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1154 | |
1117 | } else if (!strcmp("Linux", str)) { | 1155 | if (ACPI_SUCCESS(status)) |
1118 | acpi_cmdline_osi_linux(1); /* enable */ | 1156 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1119 | } else { | 1157 | } else { |
1120 | if (acpi_install_interface(str) == AE_OK) | 1158 | status = acpi_remove_interface(str); |
1121 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1159 | |
1160 | if (ACPI_SUCCESS(status)) | ||
1161 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | ||
1162 | } | ||
1122 | } | 1163 | } |
1123 | } | 1164 | } |
1124 | 1165 | ||
1125 | int __init acpi_osi_setup(char *str) | 1166 | static int __init osi_setup(char *str) |
1126 | { | 1167 | { |
1127 | if (str == NULL || *str == '\0') { | 1168 | if (str && !strcmp("Linux", str)) |
1128 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1169 | acpi_cmdline_osi_linux(1); |
1129 | acpi_gbl_create_osi_method = FALSE; | 1170 | else if (str && !strcmp("!Linux", str)) |
1130 | } else { | 1171 | acpi_cmdline_osi_linux(0); |
1131 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1172 | else |
1132 | } | 1173 | acpi_osi_setup(str); |
1133 | 1174 | ||
1134 | return 1; | 1175 | return 1; |
1135 | } | 1176 | } |
1136 | 1177 | ||
1137 | __setup("acpi_osi=", acpi_osi_setup); | 1178 | __setup("acpi_osi=", osi_setup); |
1138 | 1179 | ||
1139 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ | 1180 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ |
1140 | static int __init acpi_serialize_setup(char *str) | 1181 | static int __init acpi_serialize_setup(char *str) |
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void) | |||
1530 | return AE_OK; | 1571 | return AE_OK; |
1531 | } | 1572 | } |
1532 | 1573 | ||
1533 | acpi_status acpi_os_initialize1(void) | 1574 | acpi_status __init acpi_os_initialize1(void) |
1534 | { | 1575 | { |
1535 | kacpid_wq = create_workqueue("kacpid"); | 1576 | kacpid_wq = create_workqueue("kacpid"); |
1536 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | 1577 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |