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