.. | .. |
---|
| 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); |
---|