]> Git Repo - linux.git/blob - drivers/acpi/sysfs.c
ACPI: Remove the macro PREFIX "ACPI: "
[linux.git] / drivers / acpi / sysfs.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sysfs.c - ACPI sysfs interface to userspace.
4  */
5
6 #define pr_fmt(fmt) "ACPI: " fmt
7
8 #include <linux/init.h>
9 #include <linux/kernel.h>
10 #include <linux/moduleparam.h>
11 #include <linux/acpi.h>
12
13 #include "internal.h"
14
15 #ifdef CONFIG_ACPI_DEBUG
16 /*
17  * ACPI debug sysfs I/F, including:
18  * /sys/modules/acpi/parameters/debug_layer
19  * /sys/modules/acpi/parameters/debug_level
20  * /sys/modules/acpi/parameters/trace_method_name
21  * /sys/modules/acpi/parameters/trace_state
22  * /sys/modules/acpi/parameters/trace_debug_layer
23  * /sys/modules/acpi/parameters/trace_debug_level
24  */
25
26 struct acpi_dlayer {
27         const char *name;
28         unsigned long value;
29 };
30 struct acpi_dlevel {
31         const char *name;
32         unsigned long value;
33 };
34 #define ACPI_DEBUG_INIT(v)      { .name = #v, .value = v }
35
36 static const struct acpi_dlayer acpi_debug_layers[] = {
37         ACPI_DEBUG_INIT(ACPI_UTILITIES),
38         ACPI_DEBUG_INIT(ACPI_HARDWARE),
39         ACPI_DEBUG_INIT(ACPI_EVENTS),
40         ACPI_DEBUG_INIT(ACPI_TABLES),
41         ACPI_DEBUG_INIT(ACPI_NAMESPACE),
42         ACPI_DEBUG_INIT(ACPI_PARSER),
43         ACPI_DEBUG_INIT(ACPI_DISPATCHER),
44         ACPI_DEBUG_INIT(ACPI_EXECUTER),
45         ACPI_DEBUG_INIT(ACPI_RESOURCES),
46         ACPI_DEBUG_INIT(ACPI_CA_DEBUGGER),
47         ACPI_DEBUG_INIT(ACPI_OS_SERVICES),
48         ACPI_DEBUG_INIT(ACPI_CA_DISASSEMBLER),
49         ACPI_DEBUG_INIT(ACPI_COMPILER),
50         ACPI_DEBUG_INIT(ACPI_TOOLS),
51 };
52
53 static const struct acpi_dlevel acpi_debug_levels[] = {
54         ACPI_DEBUG_INIT(ACPI_LV_INIT),
55         ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT),
56         ACPI_DEBUG_INIT(ACPI_LV_INFO),
57         ACPI_DEBUG_INIT(ACPI_LV_REPAIR),
58         ACPI_DEBUG_INIT(ACPI_LV_TRACE_POINT),
59
60         ACPI_DEBUG_INIT(ACPI_LV_INIT_NAMES),
61         ACPI_DEBUG_INIT(ACPI_LV_PARSE),
62         ACPI_DEBUG_INIT(ACPI_LV_LOAD),
63         ACPI_DEBUG_INIT(ACPI_LV_DISPATCH),
64         ACPI_DEBUG_INIT(ACPI_LV_EXEC),
65         ACPI_DEBUG_INIT(ACPI_LV_NAMES),
66         ACPI_DEBUG_INIT(ACPI_LV_OPREGION),
67         ACPI_DEBUG_INIT(ACPI_LV_BFIELD),
68         ACPI_DEBUG_INIT(ACPI_LV_TABLES),
69         ACPI_DEBUG_INIT(ACPI_LV_VALUES),
70         ACPI_DEBUG_INIT(ACPI_LV_OBJECTS),
71         ACPI_DEBUG_INIT(ACPI_LV_RESOURCES),
72         ACPI_DEBUG_INIT(ACPI_LV_USER_REQUESTS),
73         ACPI_DEBUG_INIT(ACPI_LV_PACKAGE),
74
75         ACPI_DEBUG_INIT(ACPI_LV_ALLOCATIONS),
76         ACPI_DEBUG_INIT(ACPI_LV_FUNCTIONS),
77         ACPI_DEBUG_INIT(ACPI_LV_OPTIMIZATIONS),
78
79         ACPI_DEBUG_INIT(ACPI_LV_MUTEX),
80         ACPI_DEBUG_INIT(ACPI_LV_THREADS),
81         ACPI_DEBUG_INIT(ACPI_LV_IO),
82         ACPI_DEBUG_INIT(ACPI_LV_INTERRUPTS),
83
84         ACPI_DEBUG_INIT(ACPI_LV_AML_DISASSEMBLE),
85         ACPI_DEBUG_INIT(ACPI_LV_VERBOSE_INFO),
86         ACPI_DEBUG_INIT(ACPI_LV_FULL_TABLES),
87         ACPI_DEBUG_INIT(ACPI_LV_EVENTS),
88 };
89
90 static int param_get_debug_layer(char *buffer, const struct kernel_param *kp)
91 {
92         int result = 0;
93         int i;
94
95         result = sprintf(buffer, "%-25s\tHex        SET\n", "Description");
96
97         for (i = 0; i < ARRAY_SIZE(acpi_debug_layers); i++) {
98                 result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n",
99                                   acpi_debug_layers[i].name,
100                                   acpi_debug_layers[i].value,
101                                   (acpi_dbg_layer & acpi_debug_layers[i].value)
102                                   ? '*' : ' ');
103         }
104         result +=
105             sprintf(buffer + result, "%-25s\t0x%08X [%c]\n", "ACPI_ALL_DRIVERS",
106                     ACPI_ALL_DRIVERS,
107                     (acpi_dbg_layer & ACPI_ALL_DRIVERS) ==
108                     ACPI_ALL_DRIVERS ? '*' : (acpi_dbg_layer & ACPI_ALL_DRIVERS)
109                     == 0 ? ' ' : '-');
110         result +=
111             sprintf(buffer + result,
112                     "--\ndebug_layer = 0x%08X ( * = enabled)\n",
113                     acpi_dbg_layer);
114
115         return result;
116 }
117
118 static int param_get_debug_level(char *buffer, const struct kernel_param *kp)
119 {
120         int result = 0;
121         int i;
122
123         result = sprintf(buffer, "%-25s\tHex        SET\n", "Description");
124
125         for (i = 0; i < ARRAY_SIZE(acpi_debug_levels); i++) {
126                 result += sprintf(buffer + result, "%-25s\t0x%08lX [%c]\n",
127                                   acpi_debug_levels[i].name,
128                                   acpi_debug_levels[i].value,
129                                   (acpi_dbg_level & acpi_debug_levels[i].value)
130                                   ? '*' : ' ');
131         }
132         result +=
133             sprintf(buffer + result, "--\ndebug_level = 0x%08X (* = enabled)\n",
134                     acpi_dbg_level);
135
136         return result;
137 }
138
139 static const struct kernel_param_ops param_ops_debug_layer = {
140         .set = param_set_uint,
141         .get = param_get_debug_layer,
142 };
143
144 static const struct kernel_param_ops param_ops_debug_level = {
145         .set = param_set_uint,
146         .get = param_get_debug_level,
147 };
148
149 module_param_cb(debug_layer, &param_ops_debug_layer, &acpi_dbg_layer, 0644);
150 module_param_cb(debug_level, &param_ops_debug_level, &acpi_dbg_level, 0644);
151
152 static char trace_method_name[1024];
153
154 static int param_set_trace_method_name(const char *val,
155                                        const struct kernel_param *kp)
156 {
157         u32 saved_flags = 0;
158         bool is_abs_path = true;
159
160         if (*val != '\\')
161                 is_abs_path = false;
162
163         if ((is_abs_path && strlen(val) > 1023) ||
164             (!is_abs_path && strlen(val) > 1022)) {
165                 pr_err("%s: string parameter too long\n", kp->name);
166                 return -ENOSPC;
167         }
168
169         /*
170          * It's not safe to update acpi_gbl_trace_method_name without
171          * having the tracer stopped, so we save the original tracer
172          * state and disable it.
173          */
174         saved_flags = acpi_gbl_trace_flags;
175         (void)acpi_debug_trace(NULL,
176                                acpi_gbl_trace_dbg_level,
177                                acpi_gbl_trace_dbg_layer,
178                                0);
179
180         /* This is a hack.  We can't kmalloc in early boot. */
181         if (is_abs_path)
182                 strcpy(trace_method_name, val);
183         else {
184                 trace_method_name[0] = '\\';
185                 strcpy(trace_method_name+1, val);
186         }
187
188         /* Restore the original tracer state */
189         (void)acpi_debug_trace(trace_method_name,
190                                acpi_gbl_trace_dbg_level,
191                                acpi_gbl_trace_dbg_layer,
192                                saved_flags);
193
194         return 0;
195 }
196
197 static int param_get_trace_method_name(char *buffer, const struct kernel_param *kp)
198 {
199         return scnprintf(buffer, PAGE_SIZE, "%s\n", acpi_gbl_trace_method_name);
200 }
201
202 static const struct kernel_param_ops param_ops_trace_method = {
203         .set = param_set_trace_method_name,
204         .get = param_get_trace_method_name,
205 };
206
207 static const struct kernel_param_ops param_ops_trace_attrib = {
208         .set = param_set_uint,
209         .get = param_get_uint,
210 };
211
212 module_param_cb(trace_method_name, &param_ops_trace_method, &trace_method_name, 0644);
213 module_param_cb(trace_debug_layer, &param_ops_trace_attrib, &acpi_gbl_trace_dbg_layer, 0644);
214 module_param_cb(trace_debug_level, &param_ops_trace_attrib, &acpi_gbl_trace_dbg_level, 0644);
215
216 static int param_set_trace_state(const char *val,
217                                  const struct kernel_param *kp)
218 {
219         acpi_status status;
220         const char *method = trace_method_name;
221         u32 flags = 0;
222
223 /* So "xxx-once" comparison should go prior than "xxx" comparison */
224 #define acpi_compare_param(val, key)    \
225         strncmp((val), (key), sizeof(key) - 1)
226
227         if (!acpi_compare_param(val, "enable")) {
228                 method = NULL;
229                 flags = ACPI_TRACE_ENABLED;
230         } else if (!acpi_compare_param(val, "disable"))
231                 method = NULL;
232         else if (!acpi_compare_param(val, "method-once"))
233                 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT;
234         else if (!acpi_compare_param(val, "method"))
235                 flags = ACPI_TRACE_ENABLED;
236         else if (!acpi_compare_param(val, "opcode-once"))
237                 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_ONESHOT | ACPI_TRACE_OPCODE;
238         else if (!acpi_compare_param(val, "opcode"))
239                 flags = ACPI_TRACE_ENABLED | ACPI_TRACE_OPCODE;
240         else
241                 return -EINVAL;
242
243         status = acpi_debug_trace(method,
244                                   acpi_gbl_trace_dbg_level,
245                                   acpi_gbl_trace_dbg_layer,
246                                   flags);
247         if (ACPI_FAILURE(status))
248                 return -EBUSY;
249
250         return 0;
251 }
252
253 static int param_get_trace_state(char *buffer, const struct kernel_param *kp)
254 {
255         if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED))
256                 return sprintf(buffer, "disable\n");
257         else {
258                 if (acpi_gbl_trace_method_name) {
259                         if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT)
260                                 return sprintf(buffer, "method-once\n");
261                         else
262                                 return sprintf(buffer, "method\n");
263                 } else
264                         return sprintf(buffer, "enable\n");
265         }
266         return 0;
267 }
268
269 module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
270                   NULL, 0644);
271 #endif /* CONFIG_ACPI_DEBUG */
272
273
274 /* /sys/modules/acpi/parameters/aml_debug_output */
275
276 module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
277                    byte, 0644);
278 MODULE_PARM_DESC(aml_debug_output,
279                  "To enable/disable the ACPI Debug Object output.");
280
281 /* /sys/module/acpi/parameters/acpica_version */
282 static int param_get_acpica_version(char *buffer,
283                                     const struct kernel_param *kp)
284 {
285         int result;
286
287         result = sprintf(buffer, "%x\n", ACPI_CA_VERSION);
288
289         return result;
290 }
291
292 module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
293
294 /*
295  * ACPI table sysfs I/F:
296  * /sys/firmware/acpi/tables/
297  * /sys/firmware/acpi/tables/data/
298  * /sys/firmware/acpi/tables/dynamic/
299  */
300
301 static LIST_HEAD(acpi_table_attr_list);
302 static struct kobject *tables_kobj;
303 static struct kobject *tables_data_kobj;
304 static struct kobject *dynamic_tables_kobj;
305 static struct kobject *hotplug_kobj;
306
307 #define ACPI_MAX_TABLE_INSTANCES        999
308 #define ACPI_INST_SIZE                  4 /* including trailing 0 */
309
310 struct acpi_table_attr {
311         struct bin_attribute attr;
312         char name[ACPI_NAMESEG_SIZE];
313         int instance;
314         char filename[ACPI_NAMESEG_SIZE+ACPI_INST_SIZE];
315         struct list_head node;
316 };
317
318 struct acpi_data_attr {
319         struct bin_attribute attr;
320         u64     addr;
321 };
322
323 static ssize_t acpi_table_show(struct file *filp, struct kobject *kobj,
324                                struct bin_attribute *bin_attr, char *buf,
325                                loff_t offset, size_t count)
326 {
327         struct acpi_table_attr *table_attr =
328             container_of(bin_attr, struct acpi_table_attr, attr);
329         struct acpi_table_header *table_header = NULL;
330         acpi_status status;
331         ssize_t rc;
332
333         status = acpi_get_table(table_attr->name, table_attr->instance,
334                                 &table_header);
335         if (ACPI_FAILURE(status))
336                 return -ENODEV;
337
338         rc = memory_read_from_buffer(buf, count, &offset, table_header,
339                         table_header->length);
340         acpi_put_table(table_header);
341         return rc;
342 }
343
344 static int acpi_table_attr_init(struct kobject *tables_obj,
345                                 struct acpi_table_attr *table_attr,
346                                 struct acpi_table_header *table_header)
347 {
348         struct acpi_table_header *header = NULL;
349         struct acpi_table_attr *attr = NULL;
350         char instance_str[ACPI_INST_SIZE];
351
352         sysfs_attr_init(&table_attr->attr.attr);
353         ACPI_COPY_NAMESEG(table_attr->name, table_header->signature);
354
355         list_for_each_entry(attr, &acpi_table_attr_list, node) {
356                 if (ACPI_COMPARE_NAMESEG(table_attr->name, attr->name))
357                         if (table_attr->instance < attr->instance)
358                                 table_attr->instance = attr->instance;
359         }
360         table_attr->instance++;
361         if (table_attr->instance > ACPI_MAX_TABLE_INSTANCES) {
362                 pr_warn("%4.4s: too many table instances\n", table_attr->name);
363                 return -ERANGE;
364         }
365
366         ACPI_COPY_NAMESEG(table_attr->filename, table_header->signature);
367         table_attr->filename[ACPI_NAMESEG_SIZE] = '\0';
368         if (table_attr->instance > 1 || (table_attr->instance == 1 &&
369                                          !acpi_get_table
370                                          (table_header->signature, 2, &header))) {
371                 snprintf(instance_str, sizeof(instance_str), "%u",
372                          table_attr->instance);
373                 strcat(table_attr->filename, instance_str);
374         }
375
376         table_attr->attr.size = table_header->length;
377         table_attr->attr.read = acpi_table_show;
378         table_attr->attr.attr.name = table_attr->filename;
379         table_attr->attr.attr.mode = 0400;
380
381         return sysfs_create_bin_file(tables_obj, &table_attr->attr);
382 }
383
384 acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context)
385 {
386         struct acpi_table_attr *table_attr;
387
388         switch (event) {
389         case ACPI_TABLE_EVENT_INSTALL:
390                 table_attr =
391                     kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
392                 if (!table_attr)
393                         return AE_NO_MEMORY;
394
395                 if (acpi_table_attr_init(dynamic_tables_kobj,
396                                          table_attr, table)) {
397                         kfree(table_attr);
398                         return AE_ERROR;
399                 }
400                 list_add_tail(&table_attr->node, &acpi_table_attr_list);
401                 break;
402         case ACPI_TABLE_EVENT_LOAD:
403         case ACPI_TABLE_EVENT_UNLOAD:
404         case ACPI_TABLE_EVENT_UNINSTALL:
405                 /*
406                  * we do not need to do anything right now
407                  * because the table is not deleted from the
408                  * global table list when unloading it.
409                  */
410                 break;
411         default:
412                 return AE_BAD_PARAMETER;
413         }
414         return AE_OK;
415 }
416
417 static ssize_t acpi_data_show(struct file *filp, struct kobject *kobj,
418                               struct bin_attribute *bin_attr, char *buf,
419                               loff_t offset, size_t count)
420 {
421         struct acpi_data_attr *data_attr;
422         void __iomem *base;
423         ssize_t rc;
424
425         data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
426
427         base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size);
428         if (!base)
429                 return -ENOMEM;
430         rc = memory_read_from_buffer(buf, count, &offset, base,
431                                      data_attr->attr.size);
432         acpi_os_unmap_memory(base, data_attr->attr.size);
433
434         return rc;
435 }
436
437 static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
438 {
439         struct acpi_table_bert *bert = th;
440
441         if (bert->header.length < sizeof(struct acpi_table_bert) ||
442             bert->region_length < sizeof(struct acpi_hest_generic_status)) {
443                 kfree(data_attr);
444                 return -EINVAL;
445         }
446         data_attr->addr = bert->address;
447         data_attr->attr.size = bert->region_length;
448         data_attr->attr.attr.name = "BERT";
449
450         return sysfs_create_bin_file(tables_data_kobj, &data_attr->attr);
451 }
452
453 static struct acpi_data_obj {
454         char *name;
455         int (*fn)(void *, struct acpi_data_attr *);
456 } acpi_data_objs[] = {
457         { ACPI_SIG_BERT, acpi_bert_data_init },
458 };
459
460 #define NUM_ACPI_DATA_OBJS ARRAY_SIZE(acpi_data_objs)
461
462 static int acpi_table_data_init(struct acpi_table_header *th)
463 {
464         struct acpi_data_attr *data_attr;
465         int i;
466
467         for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) {
468                 if (ACPI_COMPARE_NAMESEG(th->signature, acpi_data_objs[i].name)) {
469                         data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL);
470                         if (!data_attr)
471                                 return -ENOMEM;
472                         sysfs_attr_init(&data_attr->attr.attr);
473                         data_attr->attr.read = acpi_data_show;
474                         data_attr->attr.attr.mode = 0400;
475                         return acpi_data_objs[i].fn(th, data_attr);
476                 }
477         }
478         return 0;
479 }
480
481 static int acpi_tables_sysfs_init(void)
482 {
483         struct acpi_table_attr *table_attr;
484         struct acpi_table_header *table_header = NULL;
485         int table_index;
486         acpi_status status;
487         int ret;
488
489         tables_kobj = kobject_create_and_add("tables", acpi_kobj);
490         if (!tables_kobj)
491                 goto err;
492
493         tables_data_kobj = kobject_create_and_add("data", tables_kobj);
494         if (!tables_data_kobj)
495                 goto err_tables_data;
496
497         dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
498         if (!dynamic_tables_kobj)
499                 goto err_dynamic_tables;
500
501         for (table_index = 0;; table_index++) {
502                 status = acpi_get_table_by_index(table_index, &table_header);
503
504                 if (status == AE_BAD_PARAMETER)
505                         break;
506
507                 if (ACPI_FAILURE(status))
508                         continue;
509
510                 table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL);
511                 if (!table_attr)
512                         return -ENOMEM;
513
514                 ret = acpi_table_attr_init(tables_kobj,
515                                            table_attr, table_header);
516                 if (ret) {
517                         kfree(table_attr);
518                         return ret;
519                 }
520                 list_add_tail(&table_attr->node, &acpi_table_attr_list);
521                 acpi_table_data_init(table_header);
522         }
523
524         kobject_uevent(tables_kobj, KOBJ_ADD);
525         kobject_uevent(tables_data_kobj, KOBJ_ADD);
526         kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
527
528         return 0;
529 err_dynamic_tables:
530         kobject_put(tables_data_kobj);
531 err_tables_data:
532         kobject_put(tables_kobj);
533 err:
534         return -ENOMEM;
535 }
536
537 /*
538  * Detailed ACPI IRQ counters:
539  * /sys/firmware/acpi/interrupts/
540  */
541
542 u32 acpi_irq_handled;
543 u32 acpi_irq_not_handled;
544
545 #define COUNT_GPE 0
546 #define COUNT_SCI 1             /* acpi_irq_handled */
547 #define COUNT_SCI_NOT 2         /* acpi_irq_not_handled */
548 #define COUNT_ERROR 3           /* other */
549 #define NUM_COUNTERS_EXTRA 4
550
551 struct event_counter {
552         u32 count;
553         u32 flags;
554 };
555
556 static struct event_counter *all_counters;
557 static u32 num_gpes;
558 static u32 num_counters;
559 static struct attribute **all_attrs;
560 static u32 acpi_gpe_count;
561
562 static struct attribute_group interrupt_stats_attr_group = {
563         .name = "interrupts",
564 };
565
566 static struct kobj_attribute *counter_attrs;
567
568 static void delete_gpe_attr_array(void)
569 {
570         struct event_counter *tmp = all_counters;
571
572         all_counters = NULL;
573         kfree(tmp);
574
575         if (counter_attrs) {
576                 int i;
577
578                 for (i = 0; i < num_gpes; i++)
579                         kfree(counter_attrs[i].attr.name);
580
581                 kfree(counter_attrs);
582         }
583         kfree(all_attrs);
584
585         return;
586 }
587
588 static void gpe_count(u32 gpe_number)
589 {
590         acpi_gpe_count++;
591
592         if (!all_counters)
593                 return;
594
595         if (gpe_number < num_gpes)
596                 all_counters[gpe_number].count++;
597         else
598                 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
599                              COUNT_ERROR].count++;
600
601         return;
602 }
603
604 static void fixed_event_count(u32 event_number)
605 {
606         if (!all_counters)
607                 return;
608
609         if (event_number < ACPI_NUM_FIXED_EVENTS)
610                 all_counters[num_gpes + event_number].count++;
611         else
612                 all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS +
613                              COUNT_ERROR].count++;
614
615         return;
616 }
617
618 static void acpi_global_event_handler(u32 event_type, acpi_handle device,
619         u32 event_number, void *context)
620 {
621         if (event_type == ACPI_EVENT_TYPE_GPE) {
622                 gpe_count(event_number);
623                 pr_debug("GPE event 0x%02x\n", event_number);
624         } else if (event_type == ACPI_EVENT_TYPE_FIXED) {
625                 fixed_event_count(event_number);
626                 pr_debug("Fixed event 0x%02x\n", event_number);
627         } else {
628                 pr_debug("Other event 0x%02x\n", event_number);
629         }
630 }
631
632 static int get_status(u32 index, acpi_event_status *ret,
633                       acpi_handle *handle)
634 {
635         acpi_status status;
636
637         if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
638                 return -EINVAL;
639
640         if (index < num_gpes) {
641                 status = acpi_get_gpe_device(index, handle);
642                 if (ACPI_FAILURE(status)) {
643                         pr_warn("Invalid GPE 0x%x", index);
644                         return -ENXIO;
645                 }
646                 status = acpi_get_gpe_status(*handle, index, ret);
647         } else {
648                 status = acpi_get_event_status(index - num_gpes, ret);
649         }
650         if (ACPI_FAILURE(status))
651                 return -EIO;
652
653         return 0;
654 }
655
656 static ssize_t counter_show(struct kobject *kobj,
657                             struct kobj_attribute *attr, char *buf)
658 {
659         int index = attr - counter_attrs;
660         int size;
661         acpi_handle handle;
662         acpi_event_status status;
663         int result = 0;
664
665         all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI].count =
666             acpi_irq_handled;
667         all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT].count =
668             acpi_irq_not_handled;
669         all_counters[num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE].count =
670             acpi_gpe_count;
671         size = sprintf(buf, "%8u", all_counters[index].count);
672
673         /* "gpe_all" or "sci" */
674         if (index >= num_gpes + ACPI_NUM_FIXED_EVENTS)
675                 goto end;
676
677         result = get_status(index, &status, &handle);
678         if (result)
679                 goto end;
680
681         if (status & ACPI_EVENT_FLAG_ENABLE_SET)
682                 size += sprintf(buf + size, "  EN");
683         else
684                 size += sprintf(buf + size, "    ");
685         if (status & ACPI_EVENT_FLAG_STATUS_SET)
686                 size += sprintf(buf + size, " STS");
687         else
688                 size += sprintf(buf + size, "    ");
689
690         if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER))
691                 size += sprintf(buf + size, " invalid     ");
692         else if (status & ACPI_EVENT_FLAG_ENABLED)
693                 size += sprintf(buf + size, " enabled     ");
694         else if (status & ACPI_EVENT_FLAG_WAKE_ENABLED)
695                 size += sprintf(buf + size, " wake_enabled");
696         else
697                 size += sprintf(buf + size, " disabled    ");
698         if (status & ACPI_EVENT_FLAG_MASKED)
699                 size += sprintf(buf + size, " masked  ");
700         else
701                 size += sprintf(buf + size, " unmasked");
702
703 end:
704         size += sprintf(buf + size, "\n");
705         return result ? result : size;
706 }
707
708 /*
709  * counter_set() sets the specified counter.
710  * setting the total "sci" file to any value clears all counters.
711  * enable/disable/clear a gpe/fixed event in user space.
712  */
713 static ssize_t counter_set(struct kobject *kobj,
714                            struct kobj_attribute *attr, const char *buf,
715                            size_t size)
716 {
717         int index = attr - counter_attrs;
718         acpi_event_status status;
719         acpi_handle handle;
720         int result = 0;
721         unsigned long tmp;
722
723         if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) {
724                 int i;
725                 for (i = 0; i < num_counters; ++i)
726                         all_counters[i].count = 0;
727                 acpi_gpe_count = 0;
728                 acpi_irq_handled = 0;
729                 acpi_irq_not_handled = 0;
730                 goto end;
731         }
732
733         /* show the event status for both GPEs and Fixed Events */
734         result = get_status(index, &status, &handle);
735         if (result)
736                 goto end;
737
738         if (!(status & ACPI_EVENT_FLAG_HAS_HANDLER)) {
739                 pr_warn("Can not change Invalid GPE/Fixed Event status\n");
740                 return -EINVAL;
741         }
742
743         if (index < num_gpes) {
744                 if (!strcmp(buf, "disable\n") &&
745                     (status & ACPI_EVENT_FLAG_ENABLED))
746                         result = acpi_disable_gpe(handle, index);
747                 else if (!strcmp(buf, "enable\n") &&
748                          !(status & ACPI_EVENT_FLAG_ENABLED))
749                         result = acpi_enable_gpe(handle, index);
750                 else if (!strcmp(buf, "clear\n") &&
751                          (status & ACPI_EVENT_FLAG_STATUS_SET))
752                         result = acpi_clear_gpe(handle, index);
753                 else if (!strcmp(buf, "mask\n"))
754                         result = acpi_mask_gpe(handle, index, TRUE);
755                 else if (!strcmp(buf, "unmask\n"))
756                         result = acpi_mask_gpe(handle, index, FALSE);
757                 else if (!kstrtoul(buf, 0, &tmp))
758                         all_counters[index].count = tmp;
759                 else
760                         result = -EINVAL;
761         } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) {
762                 int event = index - num_gpes;
763                 if (!strcmp(buf, "disable\n") &&
764                     (status & ACPI_EVENT_FLAG_ENABLE_SET))
765                         result = acpi_disable_event(event, ACPI_NOT_ISR);
766                 else if (!strcmp(buf, "enable\n") &&
767                          !(status & ACPI_EVENT_FLAG_ENABLE_SET))
768                         result = acpi_enable_event(event, ACPI_NOT_ISR);
769                 else if (!strcmp(buf, "clear\n") &&
770                          (status & ACPI_EVENT_FLAG_STATUS_SET))
771                         result = acpi_clear_event(event);
772                 else if (!kstrtoul(buf, 0, &tmp))
773                         all_counters[index].count = tmp;
774                 else
775                         result = -EINVAL;
776         } else
777                 all_counters[index].count = strtoul(buf, NULL, 0);
778
779         if (ACPI_FAILURE(result))
780                 result = -EINVAL;
781 end:
782         return result ? result : size;
783 }
784
785 /*
786  * A Quirk Mechanism for GPE Flooding Prevention:
787  *
788  * Quirks may be needed to prevent GPE flooding on a specific GPE. The
789  * flooding typically cannot be detected and automatically prevented by
790  * ACPI_GPE_DISPATCH_NONE check because there is a _Lxx/_Exx prepared in
791  * the AML tables. This normally indicates a feature gap in Linux, thus
792  * instead of providing endless quirk tables, we provide a boot parameter
793  * for those who want this quirk. For example, if the users want to prevent
794  * the GPE flooding for GPE 00, they need to specify the following boot
795  * parameter:
796  *   acpi_mask_gpe=0x00
797  * The masking status can be modified by the following runtime controlling
798  * interface:
799  *   echo unmask > /sys/firmware/acpi/interrupts/gpe00
800  */
801 #define ACPI_MASKABLE_GPE_MAX   0x100
802 static DECLARE_BITMAP(acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) __initdata;
803
804 static int __init acpi_gpe_set_masked_gpes(char *val)
805 {
806         u8 gpe;
807
808         if (kstrtou8(val, 0, &gpe))
809                 return -EINVAL;
810         set_bit(gpe, acpi_masked_gpes_map);
811
812         return 1;
813 }
814 __setup("acpi_mask_gpe=", acpi_gpe_set_masked_gpes);
815
816 void __init acpi_gpe_apply_masked_gpes(void)
817 {
818         acpi_handle handle;
819         acpi_status status;
820         u16 gpe;
821
822         for_each_set_bit(gpe, acpi_masked_gpes_map, ACPI_MASKABLE_GPE_MAX) {
823                 status = acpi_get_gpe_device(gpe, &handle);
824                 if (ACPI_SUCCESS(status)) {
825                         pr_info("Masking GPE 0x%x.\n", gpe);
826                         (void)acpi_mask_gpe(handle, gpe, TRUE);
827                 }
828         }
829 }
830
831 void acpi_irq_stats_init(void)
832 {
833         acpi_status status;
834         int i;
835
836         if (all_counters)
837                 return;
838
839         num_gpes = acpi_current_gpe_count;
840         num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA;
841
842         all_attrs = kcalloc(num_counters + 1, sizeof(struct attribute *),
843                             GFP_KERNEL);
844         if (all_attrs == NULL)
845                 return;
846
847         all_counters = kcalloc(num_counters, sizeof(struct event_counter),
848                                GFP_KERNEL);
849         if (all_counters == NULL)
850                 goto fail;
851
852         status = acpi_install_global_event_handler(acpi_global_event_handler, NULL);
853         if (ACPI_FAILURE(status))
854                 goto fail;
855
856         counter_attrs = kcalloc(num_counters, sizeof(struct kobj_attribute),
857                                 GFP_KERNEL);
858         if (counter_attrs == NULL)
859                 goto fail;
860
861         for (i = 0; i < num_counters; ++i) {
862                 char buffer[12];
863                 char *name;
864
865                 if (i < num_gpes)
866                         sprintf(buffer, "gpe%02X", i);
867                 else if (i == num_gpes + ACPI_EVENT_PMTIMER)
868                         sprintf(buffer, "ff_pmtimer");
869                 else if (i == num_gpes + ACPI_EVENT_GLOBAL)
870                         sprintf(buffer, "ff_gbl_lock");
871                 else if (i == num_gpes + ACPI_EVENT_POWER_BUTTON)
872                         sprintf(buffer, "ff_pwr_btn");
873                 else if (i == num_gpes + ACPI_EVENT_SLEEP_BUTTON)
874                         sprintf(buffer, "ff_slp_btn");
875                 else if (i == num_gpes + ACPI_EVENT_RTC)
876                         sprintf(buffer, "ff_rt_clk");
877                 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_GPE)
878                         sprintf(buffer, "gpe_all");
879                 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI)
880                         sprintf(buffer, "sci");
881                 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI_NOT)
882                         sprintf(buffer, "sci_not");
883                 else if (i == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_ERROR)
884                         sprintf(buffer, "error");
885                 else
886                         sprintf(buffer, "bug%02X", i);
887
888                 name = kstrdup(buffer, GFP_KERNEL);
889                 if (name == NULL)
890                         goto fail;
891
892                 sysfs_attr_init(&counter_attrs[i].attr);
893                 counter_attrs[i].attr.name = name;
894                 counter_attrs[i].attr.mode = 0644;
895                 counter_attrs[i].show = counter_show;
896                 counter_attrs[i].store = counter_set;
897
898                 all_attrs[i] = &counter_attrs[i].attr;
899         }
900
901         interrupt_stats_attr_group.attrs = all_attrs;
902         if (!sysfs_create_group(acpi_kobj, &interrupt_stats_attr_group))
903                 return;
904
905 fail:
906         delete_gpe_attr_array();
907         return;
908 }
909
910 static void __exit interrupt_stats_exit(void)
911 {
912         sysfs_remove_group(acpi_kobj, &interrupt_stats_attr_group);
913
914         delete_gpe_attr_array();
915
916         return;
917 }
918
919 static ssize_t
920 acpi_show_profile(struct kobject *kobj, struct kobj_attribute *attr,
921                   char *buf)
922 {
923         return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile);
924 }
925
926 static const struct kobj_attribute pm_profile_attr =
927         __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL);
928
929 static ssize_t hotplug_enabled_show(struct kobject *kobj,
930                                     struct kobj_attribute *attr, char *buf)
931 {
932         struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
933
934         return sprintf(buf, "%d\n", hotplug->enabled);
935 }
936
937 static ssize_t hotplug_enabled_store(struct kobject *kobj,
938                                      struct kobj_attribute *attr,
939                                      const char *buf, size_t size)
940 {
941         struct acpi_hotplug_profile *hotplug = to_acpi_hotplug_profile(kobj);
942         unsigned int val;
943
944         if (kstrtouint(buf, 10, &val) || val > 1)
945                 return -EINVAL;
946
947         acpi_scan_hotplug_enabled(hotplug, val);
948         return size;
949 }
950
951 static struct kobj_attribute hotplug_enabled_attr =
952         __ATTR(enabled, S_IRUGO | S_IWUSR, hotplug_enabled_show,
953                 hotplug_enabled_store);
954
955 static struct attribute *hotplug_profile_attrs[] = {
956         &hotplug_enabled_attr.attr,
957         NULL
958 };
959
960 static struct kobj_type acpi_hotplug_profile_ktype = {
961         .sysfs_ops = &kobj_sysfs_ops,
962         .default_attrs = hotplug_profile_attrs,
963 };
964
965 void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
966                                     const char *name)
967 {
968         int error;
969
970         if (!hotplug_kobj)
971                 goto err_out;
972
973         error = kobject_init_and_add(&hotplug->kobj,
974                 &acpi_hotplug_profile_ktype, hotplug_kobj, "%s", name);
975         if (error) {
976                 kobject_put(&hotplug->kobj);
977                 goto err_out;
978         }
979
980         kobject_uevent(&hotplug->kobj, KOBJ_ADD);
981         return;
982
983  err_out:
984         pr_err("Unable to add hotplug profile '%s'\n", name);
985 }
986
987 static ssize_t force_remove_show(struct kobject *kobj,
988                                  struct kobj_attribute *attr, char *buf)
989 {
990         return sprintf(buf, "%d\n", 0);
991 }
992
993 static ssize_t force_remove_store(struct kobject *kobj,
994                                   struct kobj_attribute *attr,
995                                   const char *buf, size_t size)
996 {
997         bool val;
998         int ret;
999
1000         ret = strtobool(buf, &val);
1001         if (ret < 0)
1002                 return ret;
1003
1004         if (val) {
1005                 pr_err("Enabling force_remove is not supported anymore. Please report to [email protected] if you depend on this functionality\n");
1006                 return -EINVAL;
1007         }
1008         return size;
1009 }
1010
1011 static const struct kobj_attribute force_remove_attr =
1012         __ATTR(force_remove, S_IRUGO | S_IWUSR, force_remove_show,
1013                force_remove_store);
1014
1015 int __init acpi_sysfs_init(void)
1016 {
1017         int result;
1018
1019         result = acpi_tables_sysfs_init();
1020         if (result)
1021                 return result;
1022
1023         hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
1024         if (!hotplug_kobj)
1025                 return -ENOMEM;
1026
1027         result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr);
1028         if (result)
1029                 return result;
1030
1031         result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
1032         return result;
1033 }
This page took 0.092632 seconds and 4 git commands to generate.