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