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

DRM: Add a new 'boot_display' attribute

On systems with multiple GPUs there can be uncertainty which GPU is the
primary one used to drive the display at bootup. In some desktop
environments this can lead to increased power consumption because
secondary GPUs may be used for rendering and never go to a low power
state. In order to disambiguate this add a new sysfs attribute
'boot_display' that uses the output of video_is_primary_device() to
populate whether the PCI device was used for driving the display.

Suggested-by: Manivannan Sadhasivam <mani@kernel.org>
Acked-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://gitlab.freedesktop.org/xorg/lib/libpciaccess/-/issues/23
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20250811162606.587759-5-superm1@kernel.org
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>

+49
+8
Documentation/ABI/testing/sysfs-class-drm
··· 1 + What: /sys/class/drm/.../boot_display 2 + Date: January 2026 3 + Contact: Linux DRI developers <dri-devel@vger.kernel.org> 4 + Description: 5 + This file indicates that displays connected to the device were 6 + used to display the boot sequence. If a display connected to 7 + the device was used to display the boot sequence the file will 8 + be present and contain "1".
+41
drivers/gpu/drm/drm_sysfs.c
··· 18 18 #include <linux/gfp.h> 19 19 #include <linux/i2c.h> 20 20 #include <linux/kdev_t.h> 21 + #include <linux/pci.h> 21 22 #include <linux/property.h> 22 23 #include <linux/slab.h> 23 24 ··· 30 29 #include <drm/drm_print.h> 31 30 #include <drm/drm_property.h> 32 31 #include <drm/drm_sysfs.h> 32 + 33 + #include <asm/video.h> 33 34 34 35 #include "drm_internal.h" 35 36 #include "drm_crtc_internal.h" ··· 511 508 } 512 509 EXPORT_SYMBOL(drm_sysfs_connector_property_event); 513 510 511 + static ssize_t boot_display_show(struct device *dev, struct device_attribute *attr, 512 + char *buf) 513 + { 514 + return sysfs_emit(buf, "1\n"); 515 + } 516 + static DEVICE_ATTR_RO(boot_display); 517 + 518 + static struct attribute *display_attrs[] = { 519 + &dev_attr_boot_display.attr, 520 + NULL 521 + }; 522 + 523 + static umode_t boot_display_visible(struct kobject *kobj, 524 + struct attribute *a, int n) 525 + { 526 + struct device *dev = kobj_to_dev(kobj)->parent; 527 + 528 + if (dev_is_pci(dev)) { 529 + struct pci_dev *pdev = to_pci_dev(dev); 530 + 531 + if (video_is_primary_device(&pdev->dev)) 532 + return a->mode; 533 + } 534 + 535 + return 0; 536 + } 537 + 538 + static const struct attribute_group display_attr_group = { 539 + .attrs = display_attrs, 540 + .is_visible = boot_display_visible, 541 + }; 542 + 543 + static const struct attribute_group *card_dev_groups[] = { 544 + &display_attr_group, 545 + NULL 546 + }; 547 + 514 548 struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) 515 549 { 516 550 const char *minor_str; ··· 571 531 572 532 kdev->devt = MKDEV(DRM_MAJOR, minor->index); 573 533 kdev->class = drm_class; 534 + kdev->groups = card_dev_groups; 574 535 kdev->type = &drm_sysfs_device_minor; 575 536 } 576 537