aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/osl.c8
-rw-r--r--drivers/acpi/sysfs.c136
2 files changed, 108 insertions, 36 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 3b8963f21b36..6341cb523dc4 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -83,6 +83,7 @@ static void *acpi_irq_context;
83static struct workqueue_struct *kacpid_wq; 83static struct workqueue_struct *kacpid_wq;
84static struct workqueue_struct *kacpi_notify_wq; 84static struct workqueue_struct *kacpi_notify_wq;
85static struct workqueue_struct *kacpi_hotplug_wq; 85static struct workqueue_struct *kacpi_hotplug_wq;
86static bool acpi_os_initialized;
86 87
87/* 88/*
88 * This list of permanent mappings is for memory that may be accessed from 89 * This list of permanent mappings is for memory that may be accessed from
@@ -1316,6 +1317,9 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
1316 long jiffies; 1317 long jiffies;
1317 int ret = 0; 1318 int ret = 0;
1318 1319
1320 if (!acpi_os_initialized)
1321 return AE_OK;
1322
1319 if (!sem || (units < 1)) 1323 if (!sem || (units < 1))
1320 return AE_BAD_PARAMETER; 1324 return AE_BAD_PARAMETER;
1321 1325
@@ -1355,6 +1359,9 @@ acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
1355{ 1359{
1356 struct semaphore *sem = (struct semaphore *)handle; 1360 struct semaphore *sem = (struct semaphore *)handle;
1357 1361
1362 if (!acpi_os_initialized)
1363 return AE_OK;
1364
1358 if (!sem || (units < 1)) 1365 if (!sem || (units < 1))
1359 return AE_BAD_PARAMETER; 1366 return AE_BAD_PARAMETER;
1360 1367
@@ -1863,6 +1870,7 @@ acpi_status __init acpi_os_initialize(void)
1863 rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register); 1870 rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
1864 pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv); 1871 pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
1865 } 1872 }
1873 acpi_os_initialized = true;
1866 1874
1867 return AE_OK; 1875 return AE_OK;
1868} 1876}
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
index 7ab6ba46866f..8979e4a8d066 100644
--- a/drivers/acpi/sysfs.c
+++ b/drivers/acpi/sysfs.c
@@ -70,6 +70,7 @@ static const struct acpi_dlevel acpi_debug_levels[] = {
70 ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), 70 ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
71 ACPI_DEBUG_INIT(ACPI_LV_INFO), 71 ACPI_DEBUG_INIT(ACPI_LV_INFO),
72 ACPI_DEBUG_INIT(ACPI_LV_REPAIR), 72 ACPI_DEBUG_INIT(ACPI_LV_REPAIR),
73 ACPI_DEBUG_INIT(ACPI_LV_TRACE_POINT),
73 74
74 ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES), 75 ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
75 ACPI_DEBUG_INIT(ACPI_LV_PARSE), 76 ACPI_DEBUG_INIT(ACPI_LV_PARSE),
@@ -163,55 +164,118 @@ static const struct kernel_param_ops param_ops_debug_level = {
163module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644); 164module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644);
164module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644); 165module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644);
165 166
166static char trace_method_name[6]; 167static char* trace_method_name;
167module_param_string(trace_method_name, trace_method_name, 6, 0644); 168static bool trace_method_kmalloced;
168static unsigned int trace_debug_layer;
169module_param(trace_debug_layer, uint, 0644);
170static unsigned int trace_debug_level;
171module_param(trace_debug_level, uint, 0644);
172 169
173static int param_set_trace_state(const char *val, struct kernel_param *kp) 170int param_set_trace_method_name(const char *val, const struct kernel_param *kp)
174{ 171{
175 int result = 0; 172 u32 saved_flags = 0;
176 173
177 if (!strncmp(val, "enable", sizeof("enable") - 1)) { 174 if (strlen(val) > 1024) {
178 result = acpi_debug_trace(trace_method_name, trace_debug_level, 175 pr_err("%s: string parameter too long\n", kp->name);
179 trace_debug_layer, 0); 176 return -ENOSPC;
180 if (result)
181 result = -EBUSY;
182 goto exit;
183 } 177 }
184 178
185 if (!strncmp(val, "disable", sizeof("disable") - 1)) { 179 /*
186 int name = 0; 180 * It's not safe to update acpi_gbl_trace_method_name without
187 result = acpi_debug_trace((char *)&name, trace_debug_level, 181 * having the tracer stopped, so we save the original tracer
188 trace_debug_layer, 0); 182 * state and disable it.
189 if (result) 183 */
190 result = -EBUSY; 184 saved_flags = acpi_gbl_trace_flags;
191 goto exit; 185 (void)acpi_debug_trace(NULL,
192 } 186 acpi_gbl_trace_dbg_level,
187 acpi_gbl_trace_dbg_layer,
188 0);
189
190 if (trace_method_kmalloced)
191 kfree(trace_method_name);
192 trace_method_name = NULL;
193 trace_method_kmalloced = false;
194
195 /* This is a hack. We can't kmalloc in early boot. */
196 if (slab_is_available()) {
197 trace_method_name = kstrdup(val, GFP_KERNEL);
198 if (!trace_method_name)
199 return -ENOMEM;
200 trace_method_kmalloced = true;
201 } else
202 trace_method_name = (char *)val;
193 203
194 if (!strncmp(val, "1", 1)) { 204 /* Restore the original tracer state */
195 result = acpi_debug_trace(trace_method_name, trace_debug_level, 205 (void)acpi_debug_trace(trace_method_name,
196 trace_debug_layer, 1); 206 acpi_gbl_trace_dbg_level,
197 if (result) 207 acpi_gbl_trace_dbg_layer,
198 result = -EBUSY; 208 saved_flags);
199 goto exit;
200 }
201 209
202 result = -EINVAL; 210 return 0;
203exit: 211}
204 return result; 212
213static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp)
214{
215 return scnprintf(buffer, PAGE_SIZE, "%s", acpi_gbl_trace_method_name);
216}
217
218static const struct kernel_param_ops param_ops_trace_method = {
219 .set = param_set_trace_method_name,
220 .get = param_get_trace_method_name,
221};
222
223static const struct kernel_param_ops param_ops_trace_attrib = {
224 .set = param_set_uint,
225 .get = param_get_uint,
226};
227
228module_param_cb(trace_method_name, &param_ops_trace_method, &trace_method_name, 0644);
229module_param_cb(trace_debug_layer, &param_ops_trace_attrib, &acpi_gbl_trace_dbg_layer, 0644);
230module_param_cb(trace_debug_level, &param_ops_trace_attrib, &acpi_gbl_trace_dbg_level, 0644);
231
232static int param_set_trace_state(const char *val, struct kernel_param *kp)
233{
234 acpi_status status;
235 const char *method = trace_method_name;
236 u32 flags = 0;
237
238/* So "xxx-once" comparison should go prior than "xxx" comparison */
239#define acpi_compare_param(val, key) \
240 strncmp((val), (key), sizeof(key) - 1)
241
242 if (!acpi_compare_param(val, "enable")) {
243 method = NULL;
244 flags = ACPI_TRACE_ENABLED;
245 } else if (!acpi_compare_param(val, "disable"))
246 method = NULL;
247 else if (!acpi_compare_param(val, "method-once"))
248 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT;
249 else if (!acpi_compare_param(val, "method"))
250 flags = ACPI_TRACE_ENABLED;
251 else if (!acpi_compare_param(val, "opcode-once"))
252 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT | ACPI_TRACE_OPCODE;
253 else if (!acpi_compare_param(val, "opcode"))
254 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_OPCODE;
255 else
256 return -EINVAL;
257
258 status = acpi_debug_trace(method,
259 acpi_gbl_trace_dbg_level,
260 acpi_gbl_trace_dbg_layer,
261 flags);
262 if (ACPI_FAILURE(status))
263 return -EBUSY;
264
265 return 0;
205} 266}
206 267
207static int param_get_trace_state(char *buffer, struct kernel_param *kp) 268static int param_get_trace_state(char *buffer, struct kernel_param *kp)
208{ 269{
209 if (!acpi_gbl_trace_method_name) 270 if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED))
210 return sprintf(buffer, "disable"); 271 return sprintf(buffer, "disable");
211 else { 272 else {
212 if (acpi_gbl_trace_flags & 1) 273 if (acpi_gbl_trace_method_name) {
213 return sprintf(buffer, "1"); 274 if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT)
214 else 275 return sprintf(buffer, "method-once");
276 else
277 return sprintf(buffer, "method");
278 } else
215 return sprintf(buffer, "enable"); 279 return sprintf(buffer, "enable");
216 } 280 }
217 return 0; 281 return 0;