| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | |
|---|
| 2 | 3 | /* |
|---|
| 3 | 4 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support |
|---|
| .. | .. |
|---|
| 7 | 8 | * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com> |
|---|
| 8 | 9 | * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com> |
|---|
| 9 | 10 | * Copyright (c) 2003-2004 IBM Corp. |
|---|
| 10 | | - * |
|---|
| 11 | | - * This file is released under the GPLv2 |
|---|
| 12 | | - * |
|---|
| 13 | 11 | */ |
|---|
| 14 | 12 | |
|---|
| 15 | 13 | #include <linux/device.h> |
|---|
| 16 | | -#include <linux/kdev_t.h> |
|---|
| 17 | | -#include <linux/gfp.h> |
|---|
| 18 | 14 | #include <linux/err.h> |
|---|
| 19 | 15 | #include <linux/export.h> |
|---|
| 16 | +#include <linux/gfp.h> |
|---|
| 17 | +#include <linux/i2c.h> |
|---|
| 18 | +#include <linux/kdev_t.h> |
|---|
| 19 | +#include <linux/slab.h> |
|---|
| 20 | 20 | |
|---|
| 21 | +#include <drm/drm_connector.h> |
|---|
| 22 | +#include <drm/drm_device.h> |
|---|
| 23 | +#include <drm/drm_file.h> |
|---|
| 24 | +#include <drm/drm_modes.h> |
|---|
| 25 | +#include <drm/drm_print.h> |
|---|
| 26 | +#include <drm/drm_property.h> |
|---|
| 21 | 27 | #include <drm/drm_sysfs.h> |
|---|
| 22 | | -#include <drm/drmP.h> |
|---|
| 28 | + |
|---|
| 23 | 29 | #include "drm_internal.h" |
|---|
| 30 | +#include "drm_crtc_internal.h" |
|---|
| 24 | 31 | |
|---|
| 25 | 32 | #define to_drm_minor(d) dev_get_drvdata(d) |
|---|
| 26 | 33 | #define to_drm_connector(d) dev_get_drvdata(d) |
|---|
| .. | .. |
|---|
| 221 | 228 | |
|---|
| 222 | 229 | mutex_lock(&connector->dev->mode_config.mutex); |
|---|
| 223 | 230 | list_for_each_entry(mode, &connector->modes, head) { |
|---|
| 224 | | - written += snprintf(buf + written, PAGE_SIZE - written, "%s\n", |
|---|
| 231 | + written += scnprintf(buf + written, PAGE_SIZE - written, "%s\n", |
|---|
| 225 | 232 | mode->name); |
|---|
| 226 | 233 | } |
|---|
| 227 | 234 | mutex_unlock(&connector->dev->mode_config.mutex); |
|---|
| .. | .. |
|---|
| 284 | 291 | return PTR_ERR(connector->kdev); |
|---|
| 285 | 292 | } |
|---|
| 286 | 293 | |
|---|
| 287 | | - /* Let userspace know we have a new connector */ |
|---|
| 288 | | - drm_sysfs_hotplug_event(dev); |
|---|
| 289 | | - |
|---|
| 294 | + if (connector->ddc) |
|---|
| 295 | + return sysfs_create_link(&connector->kdev->kobj, |
|---|
| 296 | + &connector->ddc->dev.kobj, "ddc"); |
|---|
| 290 | 297 | return 0; |
|---|
| 291 | 298 | } |
|---|
| 292 | 299 | |
|---|
| .. | .. |
|---|
| 294 | 301 | { |
|---|
| 295 | 302 | if (!connector->kdev) |
|---|
| 296 | 303 | return; |
|---|
| 304 | + |
|---|
| 305 | + if (connector->ddc) |
|---|
| 306 | + sysfs_remove_link(&connector->kdev->kobj, "ddc"); |
|---|
| 307 | + |
|---|
| 297 | 308 | DRM_DEBUG("removing \"%s\" from sysfs\n", |
|---|
| 298 | 309 | connector->name); |
|---|
| 299 | 310 | |
|---|
| .. | .. |
|---|
| 318 | 329 | * Send a uevent for the DRM device specified by @dev. Currently we only |
|---|
| 319 | 330 | * set HOTPLUG=1 in the uevent environment, but this could be expanded to |
|---|
| 320 | 331 | * deal with other types of events. |
|---|
| 332 | + * |
|---|
| 333 | + * Any new uapi should be using the drm_sysfs_connector_status_event() |
|---|
| 334 | + * for uevents on connector status change. |
|---|
| 321 | 335 | */ |
|---|
| 322 | 336 | void drm_sysfs_hotplug_event(struct drm_device *dev) |
|---|
| 323 | 337 | { |
|---|
| .. | .. |
|---|
| 330 | 344 | } |
|---|
| 331 | 345 | EXPORT_SYMBOL(drm_sysfs_hotplug_event); |
|---|
| 332 | 346 | |
|---|
| 347 | +/** |
|---|
| 348 | + * drm_sysfs_connector_status_event - generate a DRM uevent for connector |
|---|
| 349 | + * property status change |
|---|
| 350 | + * @connector: connector on which property status changed |
|---|
| 351 | + * @property: connector property whose status changed. |
|---|
| 352 | + * |
|---|
| 353 | + * Send a uevent for the DRM device specified by @dev. Currently we |
|---|
| 354 | + * set HOTPLUG=1 and connector id along with the attached property id |
|---|
| 355 | + * related to the status change. |
|---|
| 356 | + */ |
|---|
| 357 | +void drm_sysfs_connector_status_event(struct drm_connector *connector, |
|---|
| 358 | + struct drm_property *property) |
|---|
| 359 | +{ |
|---|
| 360 | + struct drm_device *dev = connector->dev; |
|---|
| 361 | + char hotplug_str[] = "HOTPLUG=1", conn_id[21], prop_id[21]; |
|---|
| 362 | + char *envp[4] = { hotplug_str, conn_id, prop_id, NULL }; |
|---|
| 363 | + |
|---|
| 364 | + WARN_ON(!drm_mode_obj_find_prop_id(&connector->base, |
|---|
| 365 | + property->base.id)); |
|---|
| 366 | + |
|---|
| 367 | + snprintf(conn_id, ARRAY_SIZE(conn_id), |
|---|
| 368 | + "CONNECTOR=%u", connector->base.id); |
|---|
| 369 | + snprintf(prop_id, ARRAY_SIZE(prop_id), |
|---|
| 370 | + "PROPERTY=%u", property->base.id); |
|---|
| 371 | + |
|---|
| 372 | + DRM_DEBUG("generating connector status event\n"); |
|---|
| 373 | + |
|---|
| 374 | + kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); |
|---|
| 375 | +} |
|---|
| 376 | +EXPORT_SYMBOL(drm_sysfs_connector_status_event); |
|---|
| 377 | + |
|---|
| 333 | 378 | static void drm_sysfs_release(struct device *dev) |
|---|
| 334 | 379 | { |
|---|
| 335 | 380 | kfree(dev); |
|---|