drivers/gpu/drm/drm_panic.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/drm_panic.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_panic.c
Extension
.c
Size
30679 bytes
Lines
1094
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations dbg_drm_panic_ops = {
	.owner = THIS_MODULE,
	.write = debugfs_trigger_write,
	.open = simple_open,
};

static void debugfs_register_plane(struct drm_plane *plane, int index)
{
	char fname[32];

	snprintf(fname, 32, "drm_panic_plane_%d", index);
	debugfs_create_file(fname, 0200, plane->dev->debugfs_root,
			    plane, &dbg_drm_panic_ops);
}
#else
static void debugfs_register_plane(struct drm_plane *plane, int index) {}
#endif /* CONFIG_DRM_PANIC_DEBUG */

/**
 * drm_panic_is_enabled
 * @dev: the drm device that may supports drm_panic
 *
 * returns true if the drm device supports drm_panic
 */
bool drm_panic_is_enabled(struct drm_device *dev)
{
	struct drm_plane *plane;

	if (!dev->mode_config.num_total_plane)
		return false;

	drm_for_each_plane(plane, dev)
		if (plane->helper_private && plane->helper_private->get_scanout_buffer)
			return true;
	return false;
}
EXPORT_SYMBOL(drm_panic_is_enabled);

/**
 * drm_panic_register() - Initialize DRM panic for a device
 * @dev: the drm device on which the panic screen will be displayed.
 */
void drm_panic_register(struct drm_device *dev)
{
	struct drm_plane *plane;
	int registered_plane = 0;

	if (!dev->mode_config.num_total_plane)
		return;

	drm_for_each_plane(plane, dev) {
		if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
			continue;
		plane->kmsg_panic.dump = drm_panic;
		plane->kmsg_panic.max_reason = KMSG_DUMP_PANIC;
		if (kmsg_dump_register(&plane->kmsg_panic))
			drm_warn(dev, "Failed to register panic handler\n");
		else {
			debugfs_register_plane(plane, registered_plane);
			registered_plane++;
		}
	}
	if (registered_plane)
		drm_info(dev, "Registered %d planes with drm panic\n", registered_plane);
}

/**
 * drm_panic_unregister()
 * @dev: the drm device previously registered.
 */
void drm_panic_unregister(struct drm_device *dev)
{
	struct drm_plane *plane;

	if (!dev->mode_config.num_total_plane)
		return;

	drm_for_each_plane(plane, dev) {
		if (!plane->helper_private || !plane->helper_private->get_scanout_buffer)
			continue;
		kmsg_dump_unregister(&plane->kmsg_panic);
	}
}

/**
 * drm_panic_init() - initialize DRM panic.
 */
void __init drm_panic_init(void)
{
	if (drm_panic_type == -1 && drm_panic_type_set(CONFIG_DRM_PANIC_SCREEN, NULL)) {

Annotation

Implementation Notes