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

ACPI: Add acpi_handle_<level>() interfaces

This patch introduces acpi_handle_<level>(), where <level> is
a kernel message level such as err/warn/info, to support improved
logging messages for ACPI, esp. hot-plug operations.
acpi_handle_<level>() appends "ACPI" prefix and ACPI object path
to the messages. This improves diagnosis of hotplug operations
since an error message in a log file identifies an object that
caused an issue. This interface acquires the global namespace
mutex to obtain an object path. In interrupt context, it shows
the object path as <n/a>.

acpi_handle_<level>() takes acpi_handle as an argument, which is
passed to ACPI hotplug notify handlers from the ACPICA. Therefore,
it is always available unlike other kernel objects, such as device.

For example:
acpi_handle_err(handle, "Device don't exist, dropping EJECT\n");
logs an error message like this at KERN_ERR.
ACPI: \_SB_.SCK4.CPU4: Device don't exist, dropping EJECT

ACPI hot-plug drivers can use acpi_handle_<level>() when they need
to identify a target ACPI object path in their messages, such as
error cases. The usage model is similar to dev_<level>().
acpi_handle_<level>() can be used when a device is not created or
is invalid during hot-plug operations. ACPI object path is also
consistent on the platform, unlike device name that gets incremented
over hotplug operations.

ACPI drivers should use dev_<level>() when a device object is valid.
Device name provides more user friendly information, and avoids
acquiring the global ACPI namespace mutex. ACPI drivers also
continue to use pr_<level>() when they do not need to specify device
information, such as boot-up messages.

Note: ACPI_[WARNING|INFO|ERROR]() are intended for the ACPICA and
are not associated with the kernel message level.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Tested-by: Vijay Mohan Pandarathil <vijaymohan.pandarathil@hp.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Toshi Kani and committed by
Rafael J. Wysocki
fbfddae6 b59bc2fb

+81
+38
drivers/acpi/utils.c
··· 28 28 #include <linux/slab.h> 29 29 #include <linux/init.h> 30 30 #include <linux/types.h> 31 + #include <linux/hardirq.h> 32 + #include <linux/acpi.h> 31 33 #include <acpi/acpi_bus.h> 32 34 #include <acpi/acpi_drivers.h> 33 35 ··· 459 457 #endif 460 458 } 461 459 EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); 460 + 461 + /** 462 + * acpi_handle_printk: Print message with ACPI prefix and object path 463 + * 464 + * This function is called through acpi_handle_<level> macros and prints 465 + * a message with ACPI prefix and object path. This function acquires 466 + * the global namespace mutex to obtain an object path. In interrupt 467 + * context, it shows the object path as <n/a>. 468 + */ 469 + void 470 + acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) 471 + { 472 + struct va_format vaf; 473 + va_list args; 474 + struct acpi_buffer buffer = { 475 + .length = ACPI_ALLOCATE_BUFFER, 476 + .pointer = NULL 477 + }; 478 + const char *path; 479 + 480 + va_start(args, fmt); 481 + vaf.fmt = fmt; 482 + vaf.va = &args; 483 + 484 + if (in_interrupt() || 485 + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) 486 + path = "<n/a>"; 487 + else 488 + path = buffer.pointer; 489 + 490 + printk("%sACPI: %s: %pV", level, path, &vaf); 491 + 492 + va_end(args); 493 + kfree(buffer.pointer); 494 + } 495 + EXPORT_SYMBOL(acpi_handle_printk);
+43
include/linux/acpi.h
··· 434 434 #define acpi_os_set_prepare_sleep(func, pm1a_ctrl, pm1b_ctrl) do { } while (0) 435 435 #endif 436 436 437 + #ifdef CONFIG_ACPI 438 + __printf(3, 4) 439 + void acpi_handle_printk(const char *level, acpi_handle handle, 440 + const char *fmt, ...); 441 + #else /* !CONFIG_ACPI */ 442 + static inline __printf(3, 4) void 443 + acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {} 444 + #endif /* !CONFIG_ACPI */ 445 + 446 + /* 447 + * acpi_handle_<level>: Print message with ACPI prefix and object path 448 + * 449 + * These interfaces acquire the global namespace mutex to obtain an object 450 + * path. In interrupt context, it shows the object path as <n/a>. 451 + */ 452 + #define acpi_handle_emerg(handle, fmt, ...) \ 453 + acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__) 454 + #define acpi_handle_alert(handle, fmt, ...) \ 455 + acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__) 456 + #define acpi_handle_crit(handle, fmt, ...) \ 457 + acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__) 458 + #define acpi_handle_err(handle, fmt, ...) \ 459 + acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__) 460 + #define acpi_handle_warn(handle, fmt, ...) \ 461 + acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__) 462 + #define acpi_handle_notice(handle, fmt, ...) \ 463 + acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__) 464 + #define acpi_handle_info(handle, fmt, ...) \ 465 + acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__) 466 + 467 + /* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */ 468 + #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) 469 + #define acpi_handle_debug(handle, fmt, ...) \ 470 + acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__) 471 + #else 472 + #define acpi_handle_debug(handle, fmt, ...) \ 473 + ({ \ 474 + if (0) \ 475 + acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \ 476 + 0; \ 477 + }) 478 + #endif 479 + 437 480 #endif /*_LINUX_ACPI_H*/