1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* 4 * drm_sysfs.c - Modifications to drm_sysfs_class.c to support 5 * extra sysfs attribute from DRM. Normal drm_sysfs_class 6 * does not allow adding attributes. 7 * 8 * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com> 9 * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com> 10 * Copyright (c) 2003-2004 IBM Corp. 11 */ 12 13 #include <linux/acpi.h> 14 #include <linux/component.h> 15 #include <linux/device.h> 16 #include <linux/err.h> 17 #include <linux/export.h> 18 #include <linux/gfp.h> 19 #include <linux/i2c.h> 20 #include <linux/kdev_t.h> 21 #include <linux/pci.h> 22 #include <linux/property.h> 23 #include <linux/slab.h> 24 25 #include <drm/drm_accel.h> 26 #include <drm/drm_connector.h> 27 #include <drm/drm_device.h> 28 #include <drm/drm_file.h> 29 #include <drm/drm_modes.h> 30 #include <drm/drm_print.h> 31 #include <drm/drm_property.h> 32 #include <drm/drm_sysfs.h> 33 34 #include <asm/video.h> 35 36 #include "drm_internal.h" 37 #include "drm_crtc_internal.h" 38 39 #define to_drm_minor(d) dev_get_drvdata(d) 40 #define to_drm_connector(d) dev_get_drvdata(d) 41 42 /** 43 * DOC: overview 44 * 45 * DRM provides very little additional support to drivers for sysfs 46 * interactions, beyond just all the standard stuff. Drivers who want to expose 47 * additional sysfs properties and property groups can attach them at either 48 * &drm_device.dev or &drm_connector.kdev. 49 * 50 * Registration is automatically handled when calling drm_dev_register(), or 51 * drm_connector_register() in case of hot-plugged connectors. Unregistration is 52 * also automatically handled by drm_dev_unregister() and 53 * drm_connector_unregister(). 54 */ 55 56 static struct device_type drm_sysfs_device_minor = { 57 .name = "drm_minor" 58 }; 59 60 static struct device_type drm_sysfs_device_connector = { 61 .name = "drm_connector", 62 }; 63 64 struct class *drm_class; 65 66 #ifdef CONFIG_ACPI 67 static bool drm_connector_acpi_bus_match(struct device *dev) 68 { 69 return dev->type == &drm_sysfs_device_connector; 70 } 71 72 static struct acpi_device *drm_connector_acpi_find_companion(struct device *dev) 73 { 74 struct drm_connector *connector = to_drm_connector(dev); 75 76 return to_acpi_device_node(connector->fwnode); 77 } 78 79 static struct acpi_bus_type drm_connector_acpi_bus = { 80 .name = "drm_connector", 81 .match = drm_connector_acpi_bus_match, 82 .find_companion = drm_connector_acpi_find_companion, 83 }; 84 85 static void drm_sysfs_acpi_register(void) 86 { 87 register_acpi_bus_type(&drm_connector_acpi_bus); 88 } 89 90 static void drm_sysfs_acpi_unregister(void) 91 { 92 unregister_acpi_bus_type(&drm_connector_acpi_bus); 93 } 94 #else 95 static void drm_sysfs_acpi_register(void) { } 96 static void drm_sysfs_acpi_unregister(void) { } 97 #endif 98 99 static char *drm_devnode(const struct device *dev, umode_t *mode) 100 { 101 return kasprintf(GFP_KERNEL, "dri/%s", dev_name(dev)); 102 } 103 104 static int typec_connector_bind(struct device *dev, 105 struct device *typec_connector, void *data) 106 { 107 int ret; 108 109 ret = sysfs_create_link(&dev->kobj, &typec_connector->kobj, "typec_connector"); 110 if (ret) 111 return ret; 112 113 ret = sysfs_create_link(&typec_connector->kobj, &dev->kobj, "drm_connector"); 114 if (ret) 115 sysfs_remove_link(&dev->kobj, "typec_connector"); 116 117 return ret; 118 } 119 120 static void typec_connector_unbind(struct device *dev, 121 struct device *typec_connector, void *data) 122 { 123 sysfs_remove_link(&typec_connector->kobj, "drm_connector"); 124 sysfs_remove_link(&dev->kobj, "typec_connector"); 125 } 126 127 static const struct component_ops typec_connector_ops = { 128 .bind = typec_connector_bind, 129 .unbind = typec_connector_unbind, 130 }; 131 132 static CLASS_ATTR_STRING(version, S_IRUGO, "drm 1.1.0 20060810"); 133 134 /** 135 * drm_sysfs_init - initialize sysfs helpers 136 * 137 * This is used to create the DRM class, which is the implicit parent of any 138 * other top-level DRM sysfs objects. 139 * 140 * You must call drm_sysfs_destroy() to release the allocated resources. 141 * 142 * Return: 0 on success, negative error code on failure. 143 */ 144 int drm_sysfs_init(void) 145 { 146 int err; 147 148 drm_class = class_create("drm"); 149 if (IS_ERR(drm_class)) 150 return PTR_ERR(drm_class); 151 152 err = class_create_file(drm_class, &class_attr_version.attr); 153 if (err) { 154 class_destroy(drm_class); 155 drm_class = NULL; 156 return err; 157 } 158 159 drm_class->devnode = drm_devnode; 160 161 drm_sysfs_acpi_register(); 162 return 0; 163 } 164 165 /** 166 * drm_sysfs_destroy - destroys DRM class 167 * 168 * Destroy the DRM device class. 169 */ 170 void drm_sysfs_destroy(void) 171 { 172 if (IS_ERR_OR_NULL(drm_class)) 173 return; 174 drm_sysfs_acpi_unregister(); 175 class_remove_file(drm_class, &class_attr_version.attr); 176 class_destroy(drm_class); 177 drm_class = NULL; 178 } 179 180 static void drm_sysfs_release(struct device *dev) 181 { 182 kfree(dev); 183 } 184 185 /* 186 * Connector properties 187 */ 188 static ssize_t status_store(struct device *device, 189 struct device_attribute *attr, 190 const char *buf, size_t count) 191 { 192 struct drm_connector *connector = to_drm_connector(device); 193 struct drm_device *dev = connector->dev; 194 enum drm_connector_force old_force; 195 int ret; 196 197 ret = mutex_lock_interruptible(&dev->mode_config.mutex); 198 if (ret) 199 return ret; 200 201 old_force = connector->force; 202 203 if (sysfs_streq(buf, "detect")) 204 connector->force = 0; 205 else if (sysfs_streq(buf, "on")) 206 connector->force = DRM_FORCE_ON; 207 else if (sysfs_streq(buf, "on-digital")) 208 connector->force = DRM_FORCE_ON_DIGITAL; 209 else if (sysfs_streq(buf, "off")) 210 connector->force = DRM_FORCE_OFF; 211 else 212 ret = -EINVAL; 213 214 if (old_force != connector->force || !connector->force) { 215 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n", 216 connector->base.id, connector->name, 217 old_force, connector->force); 218 219 connector->funcs->fill_modes(connector, 220 dev->mode_config.max_width, 221 dev->mode_config.max_height); 222 } 223 224 mutex_unlock(&dev->mode_config.mutex); 225 226 return ret ? ret : count; 227 } 228 229 static ssize_t status_show(struct device *device, 230 struct device_attribute *attr, 231 char *buf) 232 { 233 struct drm_connector *connector = to_drm_connector(device); 234 enum drm_connector_status status; 235 236 status = READ_ONCE(connector->status); 237 238 return sysfs_emit(buf, "%s\n", 239 drm_get_connector_status_name(status)); 240 } 241 242 static ssize_t dpms_show(struct device *device, 243 struct device_attribute *attr, 244 char *buf) 245 { 246 struct drm_connector *connector = to_drm_connector(device); 247 int dpms; 248 249 dpms = READ_ONCE(connector->dpms); 250 251 return sysfs_emit(buf, "%s\n", drm_get_dpms_name(dpms)); 252 } 253 254 static ssize_t enabled_show(struct device *device, 255 struct device_attribute *attr, 256 char *buf) 257 { 258 struct drm_connector *connector = to_drm_connector(device); 259 bool enabled; 260 261 enabled = READ_ONCE(connector->encoder); 262 263 return sysfs_emit(buf, enabled ? "enabled\n" : "disabled\n"); 264 } 265 266 static ssize_t edid_show(struct file *filp, struct kobject *kobj, 267 const struct bin_attribute *attr, char *buf, loff_t off, 268 size_t count) 269 { 270 struct device *connector_dev = kobj_to_dev(kobj); 271 struct drm_connector *connector = to_drm_connector(connector_dev); 272 ssize_t ret; 273 274 ret = drm_edid_connector_property_show(connector, buf, off, count); 275 276 return ret; 277 } 278 279 static ssize_t modes_show(struct device *device, 280 struct device_attribute *attr, 281 char *buf) 282 { 283 struct drm_connector *connector = to_drm_connector(device); 284 struct drm_display_mode *mode; 285 int written = 0; 286 287 mutex_lock(&connector->dev->mode_config.mutex); 288 list_for_each_entry(mode, &connector->modes, head) { 289 written += scnprintf(buf + written, PAGE_SIZE - written, "%s\n", 290 mode->name); 291 } 292 mutex_unlock(&connector->dev->mode_config.mutex); 293 294 return written; 295 } 296 297 static ssize_t connector_id_show(struct device *device, 298 struct device_attribute *attr, 299 char *buf) 300 { 301 struct drm_connector *connector = to_drm_connector(device); 302 303 return sysfs_emit(buf, "%d\n", connector->base.id); 304 } 305 306 static DEVICE_ATTR_RW(status); 307 static DEVICE_ATTR_RO(enabled); 308 static DEVICE_ATTR_RO(dpms); 309 static DEVICE_ATTR_RO(modes); 310 static DEVICE_ATTR_RO(connector_id); 311 312 static struct attribute *connector_dev_attrs[] = { 313 &dev_attr_status.attr, 314 &dev_attr_enabled.attr, 315 &dev_attr_dpms.attr, 316 &dev_attr_modes.attr, 317 &dev_attr_connector_id.attr, 318 NULL 319 }; 320 321 static const struct bin_attribute edid_attr = { 322 .attr.name = "edid", 323 .attr.mode = 0444, 324 .size = 0, 325 .read = edid_show, 326 }; 327 328 static const struct bin_attribute *const connector_bin_attrs[] = { 329 &edid_attr, 330 NULL 331 }; 332 333 static const struct attribute_group connector_dev_group = { 334 .attrs = connector_dev_attrs, 335 .bin_attrs = connector_bin_attrs, 336 }; 337 338 static const struct attribute_group *connector_dev_groups[] = { 339 &connector_dev_group, 340 NULL 341 }; 342 343 int drm_sysfs_connector_add(struct drm_connector *connector) 344 { 345 struct drm_device *dev = connector->dev; 346 struct device *kdev; 347 int r; 348 349 if (connector->kdev) 350 return 0; 351 352 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); 353 if (!kdev) 354 return -ENOMEM; 355 356 device_initialize(kdev); 357 kdev->class = drm_class; 358 kdev->type = &drm_sysfs_device_connector; 359 kdev->parent = dev->primary->kdev; 360 kdev->groups = connector_dev_groups; 361 kdev->release = drm_sysfs_release; 362 dev_set_drvdata(kdev, connector); 363 364 r = dev_set_name(kdev, "card%d-%s", dev->primary->index, connector->name); 365 if (r) 366 goto err_free; 367 368 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] adding connector to sysfs\n", 369 connector->base.id, connector->name); 370 371 r = device_add(kdev); 372 if (r) { 373 drm_err(dev, "failed to register connector device: %d\n", r); 374 goto err_free; 375 } 376 377 connector->kdev = kdev; 378 379 if (dev_fwnode(kdev)) { 380 r = component_add(kdev, &typec_connector_ops); 381 if (r) 382 drm_err(dev, "failed to add component to create link to typec connector\n"); 383 } 384 385 return 0; 386 387 err_free: 388 put_device(kdev); 389 return r; 390 } 391 392 int drm_sysfs_connector_add_late(struct drm_connector *connector) 393 { 394 if (connector->ddc) 395 return sysfs_create_link(&connector->kdev->kobj, 396 &connector->ddc->dev.kobj, "ddc"); 397 398 return 0; 399 } 400 401 void drm_sysfs_connector_remove_early(struct drm_connector *connector) 402 { 403 if (connector->ddc) 404 sysfs_remove_link(&connector->kdev->kobj, "ddc"); 405 } 406 407 void drm_sysfs_connector_remove(struct drm_connector *connector) 408 { 409 if (!connector->kdev) 410 return; 411 412 if (dev_fwnode(connector->kdev)) 413 component_del(connector->kdev, &typec_connector_ops); 414 415 drm_dbg_kms(connector->dev, 416 "[CONNECTOR:%d:%s] removing connector from sysfs\n", 417 connector->base.id, connector->name); 418 419 device_unregister(connector->kdev); 420 connector->kdev = NULL; 421 } 422 423 void drm_sysfs_lease_event(struct drm_device *dev) 424 { 425 char *event_string = "LEASE=1"; 426 char *envp[] = { event_string, NULL }; 427 428 drm_dbg_lease(dev, "generating lease event\n"); 429 430 kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); 431 } 432 433 /** 434 * drm_sysfs_hotplug_event - generate a DRM uevent 435 * @dev: DRM device 436 * 437 * Send a uevent for the DRM device specified by @dev. Currently we only 438 * set HOTPLUG=1 in the uevent environment, but this could be expanded to 439 * deal with other types of events. 440 * 441 * Any new uapi should be using the drm_sysfs_connector_status_event() 442 * for uevents on connector status change. 443 */ 444 void drm_sysfs_hotplug_event(struct drm_device *dev) 445 { 446 char *event_string = "HOTPLUG=1"; 447 char *envp[] = { event_string, NULL }; 448 449 drm_dbg_kms(dev, "generating hotplug event\n"); 450 451 kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); 452 } 453 EXPORT_SYMBOL(drm_sysfs_hotplug_event); 454 455 /** 456 * drm_sysfs_connector_hotplug_event - generate a DRM uevent for any connector 457 * change 458 * @connector: connector which has changed 459 * 460 * Send a uevent for the DRM connector specified by @connector. This will send 461 * a uevent with the properties HOTPLUG=1 and CONNECTOR. 462 */ 463 void drm_sysfs_connector_hotplug_event(struct drm_connector *connector) 464 { 465 struct drm_device *dev = connector->dev; 466 char hotplug_str[] = "HOTPLUG=1", conn_id[21]; 467 char *envp[] = { hotplug_str, conn_id, NULL }; 468 469 snprintf(conn_id, sizeof(conn_id), 470 "CONNECTOR=%u", connector->base.id); 471 472 drm_dbg_kms(connector->dev, 473 "[CONNECTOR:%d:%s] generating connector hotplug event\n", 474 connector->base.id, connector->name); 475 476 kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); 477 } 478 EXPORT_SYMBOL(drm_sysfs_connector_hotplug_event); 479 480 /** 481 * drm_sysfs_connector_property_event - generate a DRM uevent for connector 482 * property change 483 * @connector: connector on which property changed 484 * @property: connector property which has changed. 485 * 486 * Send a uevent for the specified DRM connector and property. Currently we 487 * set HOTPLUG=1 and connector id along with the attached property id 488 * related to the change. 489 */ 490 void drm_sysfs_connector_property_event(struct drm_connector *connector, 491 struct drm_property *property) 492 { 493 struct drm_device *dev = connector->dev; 494 char hotplug_str[] = "HOTPLUG=1", conn_id[21], prop_id[21]; 495 char *envp[4] = { hotplug_str, conn_id, prop_id, NULL }; 496 497 WARN_ON(!drm_mode_obj_find_prop_id(&connector->base, 498 property->base.id)); 499 500 snprintf(conn_id, ARRAY_SIZE(conn_id), 501 "CONNECTOR=%u", connector->base.id); 502 snprintf(prop_id, ARRAY_SIZE(prop_id), 503 "PROPERTY=%u", property->base.id); 504 505 drm_dbg_kms(connector->dev, 506 "[CONNECTOR:%d:%s] generating connector property event for [PROP:%d:%s]\n", 507 connector->base.id, connector->name, 508 property->base.id, property->name); 509 510 kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); 511 } 512 EXPORT_SYMBOL(drm_sysfs_connector_property_event); 513 514 static ssize_t boot_display_show(struct device *dev, struct device_attribute *attr, 515 char *buf) 516 { 517 return sysfs_emit(buf, "1\n"); 518 } 519 static DEVICE_ATTR_RO(boot_display); 520 521 static struct attribute *display_attrs[] = { 522 &dev_attr_boot_display.attr, 523 NULL 524 }; 525 526 static umode_t boot_display_visible(struct kobject *kobj, 527 struct attribute *a, int n) 528 { 529 struct device *dev = kobj_to_dev(kobj)->parent; 530 531 if (dev_is_pci(dev)) { 532 struct pci_dev *pdev = to_pci_dev(dev); 533 534 if (video_is_primary_device(&pdev->dev)) 535 return a->mode; 536 } 537 538 return 0; 539 } 540 541 static const struct attribute_group display_attr_group = { 542 .attrs = display_attrs, 543 .is_visible = boot_display_visible, 544 }; 545 546 static const struct attribute_group *card_dev_groups[] = { 547 &display_attr_group, 548 NULL 549 }; 550 551 struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) 552 { 553 const char *minor_str; 554 struct device *kdev; 555 int r; 556 557 kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); 558 if (!kdev) 559 return ERR_PTR(-ENOMEM); 560 561 device_initialize(kdev); 562 563 if (minor->type == DRM_MINOR_ACCEL) { 564 minor_str = "accel%d"; 565 accel_set_device_instance_params(kdev, minor->index); 566 } else { 567 if (minor->type == DRM_MINOR_RENDER) 568 minor_str = "renderD%d"; 569 else 570 minor_str = "card%d"; 571 572 kdev->devt = MKDEV(DRM_MAJOR, minor->index); 573 kdev->class = drm_class; 574 kdev->groups = card_dev_groups; 575 kdev->type = &drm_sysfs_device_minor; 576 } 577 578 kdev->parent = minor->dev->dev; 579 kdev->release = drm_sysfs_release; 580 dev_set_drvdata(kdev, minor); 581 582 r = dev_set_name(kdev, minor_str, minor->index); 583 if (r < 0) 584 goto err_free; 585 586 return kdev; 587 588 err_free: 589 put_device(kdev); 590 return ERR_PTR(r); 591 } 592 593 /** 594 * drm_class_device_register - register new device with the DRM sysfs class 595 * @dev: device to register 596 * 597 * Registers a new &struct device within the DRM sysfs class. Essentially only 598 * used by ttm to have a place for its global settings. Drivers should never use 599 * this. 600 */ 601 int drm_class_device_register(struct device *dev) 602 { 603 if (!drm_class || IS_ERR(drm_class)) 604 return -ENOENT; 605 606 dev->class = drm_class; 607 return device_register(dev); 608 } 609 EXPORT_SYMBOL_GPL(drm_class_device_register); 610 611 /** 612 * drm_class_device_unregister - unregister device with the DRM sysfs class 613 * @dev: device to unregister 614 * 615 * Unregisters a &struct device from the DRM sysfs class. Essentially only used 616 * by ttm to have a place for its global settings. Drivers should never use 617 * this. 618 */ 619 void drm_class_device_unregister(struct device *dev) 620 { 621 return device_unregister(dev); 622 } 623 EXPORT_SYMBOL_GPL(drm_class_device_unregister); 624